#[non_exhaustive]pub enum DeadLetterReason {
UnknownPid {
pid: Pid,
context: AuditContext,
},
UnknownConversation {
conversation_id: String,
context: AuditContext,
},
VersionMismatch {
expected: String,
received: String,
context: AuditContext,
},
DuplicateMessage {
inbox_key: String,
context: AuditContext,
},
ProcessingError {
message: String,
context: AuditContext,
},
TestMessage {
context: AuditContext,
},
MissingInterchangeParty {
qualifier: &'static str,
context: AuditContext,
},
NotDispatchable {
workflow_name: String,
pid: Pid,
reason: String,
context: AuditContext,
},
OutboxExhausted {
message_id: OutboxMessageId,
message_type: String,
recipient: String,
last_error: String,
attempts: u32,
},
}Expand description
Structured reason why an inbound message was rejected.
The variant gives the dispatch path enough information to emit an
actionable CONTRL or log entry. Each variant carries an AuditContext
with the § 147 AO / GoBD fields required for regulatory audit logging.
Adding new variants is a non-breaking change thanks to #[non_exhaustive].
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
UnknownPid
No workflow is registered for this PID in the PidRouter.
The PID is either from a future BDEW release not yet deployed or a malformed message. Respond with a CONTRL negative acknowledgement.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
UnknownConversation
No in-flight process matched the inbound conversation_id.
This typically means the process completed, was never started, or
the ProcessRegistry was lost on restart (see.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
VersionMismatch
The message’s format version has no registered MessageAdapter.
Either the adapter registry is incomplete (see or the sender is using a deprecated / future format version.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
DuplicateMessage
A message with this inbox key was already accepted (AS4 duplicate).
The AS4 sender retries for up to 72 hours. The InboxStore
detected the duplicate and the message must not be processed again.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
ProcessingError
A workflow or adapter returned a processing error.
The message was routed correctly but could not be processed. Use this variant when the failure is definitive (not retriable).
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
TestMessage
An interchange flagged with UNB DE0035 = 1 (test indicator) was received on a production endpoint.
Per Allgemeine Festlegungen V6.1d §3, test interchanges must not be processed as production. The interchange is rejected at the ingest boundary without being forwarded to any workflow.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context (contains sender, receiver, control_ref).
MissingInterchangeParty
A business message arrived without the NAD party the answer is
addressed with, or the one the Sparte is resolved from.
BDEW Allgemeine Festlegungen V6.1d §2.13 identifies the fachliche
sender and receiver on message level in NAD+MS / NAD+MR DE 3035 and
states the approach applies “für alle EDI@Energy EDIFACT Nachrichten und
-dateien einheitlich”. Both are load-bearing here: the sender is who the
answer and the APERAK go back to, and the receiver is which of the
operator’s own MP-IDs — and therefore which Sparte and which Marktrolle —
the message is addressed to.
Substituting an empty MP-ID produces a process whose answer is addressed
to nobody and whose Sparte silently defaults, so the message is refused
at the boundary instead. CONTRL carries no NAD at all — it is a
UN/EDIFACT syntax acknowledgement rather than an EDI@Energy business
message — and is exempt.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
NotDispatchable
The PID resolved to a workflow, but the ingest dispatcher has no arm
for it — so makod claimed to route the message and then dropped it.
Always a coverage bug on this side, never a defect in the sender’s
message: PidRouter answered, the transport acknowledged, and the
business payload went nowhere. It is recorded rather than logged because
an acknowledged inbound message that produced no process is exactly what
§ 147 AO / GoBD require a trace of.
Fields
context: AuditContext§ 147 AO / GoBD structured audit context.
OutboxExhausted
The outbox delivery worker gave up after exhausting all retry attempts.
The message was re-queued max_attempts times and never successfully
delivered to the AS4 endpoint (or ERP webhook). The message is removed
from the outbox and recorded here for regulatory audit.
Fields
message_id: OutboxMessageIdThe outbox message ID of the undeliverable message.
Implementations§
Source§impl DeadLetterReason
impl DeadLetterReason
Sourcepub fn label(&self) -> &'static str
pub fn label(&self) -> &'static str
Short label identifying the rejection category.
Suitable for structured log fields and metric labels.
Sourcepub fn audit_context(&self) -> Option<&AuditContext>
pub fn audit_context(&self) -> Option<&AuditContext>
Return the AuditContext embedded in this reason, if present.
OutboxExhausted does not carry an AuditContext because it refers
to an outbound message (not an inbound AS4 message).
Trait Implementations§
Source§impl Clone for DeadLetterReason
impl Clone for DeadLetterReason
Source§fn clone(&self) -> DeadLetterReason
fn clone(&self) -> DeadLetterReason
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more