@@ -181,7 +181,7 @@ private async Task ProcessAsync(PreparedDelivery prepared, BasicDeliverEventArgs
181181
182182 activity ? . SetStatus ( ActivityStatusCode . Error , ex . Message ) ;
183183 activity ? . AddException ( ex ) ;
184- await HandleFailureAsync ( ex , ea , prepared . DiagnosticTypeName ) ;
184+ await HandleFailureAsync ( ex , ea , prepared . Envelope , prepared . DiagnosticTypeName ) ;
185185 }
186186 }
187187
@@ -216,7 +216,7 @@ private async Task ExecuteWithInMemoryRetryAsync(RetryPolicyDefinition policy, P
216216 activity ? . SetStatus ( ActivityStatusCode . Error , ex . Message ) ;
217217 activity ? . AddException ( ex ) ;
218218 MessagingLog . ConsumerFailed ( _logger , ex , _queueDefinition . Name , prepared . DiagnosticTypeName , ea . RoutingKey ) ;
219- await PublishFaultAsync ( ex , ea , ea . BasicProperties . Headers ?? new Dictionary < string , object ? > ( ) , prepared . DiagnosticTypeName ) ;
219+ await PublishFaultAsync ( ex , ea , ea . BasicProperties . Headers ?? new Dictionary < string , object ? > ( ) , prepared . Envelope , prepared . DiagnosticTypeName ) ;
220220 await NackAsync ( ea ) ;
221221 return ;
222222 }
@@ -262,7 +262,7 @@ private async Task ExecuteWithInMemoryRetryAsync(RetryPolicyDefinition policy, P
262262 return activity ;
263263 }
264264
265- private async Task HandleFailureAsync ( Exception ex , BasicDeliverEventArgs ea , string messageTypeName )
265+ private async Task HandleFailureAsync ( Exception ex , BasicDeliverEventArgs ea , MessageEnvelope ? envelope , string messageTypeName )
266266 {
267267 var plan = _typeCache . GetPlan ( messageTypeName ) ;
268268 var policy = GetPolicy ( plan , _queueDefinition ) ;
@@ -272,7 +272,7 @@ private async Task HandleFailureAsync(Exception ex, BasicDeliverEventArgs ea, st
272272 if ( policy is null )
273273 {
274274 MessagingLog . ConsumerFailed ( _logger , ex , _queueDefinition . Name , messageTypeName , ea . RoutingKey ) ;
275- await PublishFaultAsync ( ex , ea , headers , messageTypeName ) ;
275+ await PublishFaultAsync ( ex , ea , headers , envelope , messageTypeName ) ;
276276 await NackAsync ( ea ) ;
277277 return ;
278278 }
@@ -296,28 +296,32 @@ private async Task HandleFailureAsync(Exception ex, BasicDeliverEventArgs ea, st
296296 }
297297
298298 MessagingLog . ConsumerFailed ( _logger , ex , _queueDefinition . Name , messageTypeName , ea . RoutingKey ) ;
299- await PublishFaultAsync ( ex , ea , headers , messageTypeName ) ;
299+ await PublishFaultAsync ( ex , ea , headers , envelope , messageTypeName ) ;
300300 await NackAsync ( ea ) ;
301301 }
302302
303303 /// <summary>
304304 /// Publishes a <see cref="Fault{TMessage}"/> for a terminally-failed delivery. When the delivery carries an
305305 /// explicit <c>FaultAddress</c> the fault is routed point-to-point to that address (via the broker's default
306306 /// exchange); otherwise it is published by convention to the shared fault exchange with the faulted message's
307- /// URN as the routing key. Exactly one fault is emitted per failure. Publishing is best-effort: a failure to
308- /// publish the fault is logged and never disrupts settling the original delivery.
307+ /// URN as the routing key. Exactly one fault is emitted per failure. The fault's <c>Message</c> is the original
308+ /// message payload: for an envelope-wrapped delivery the wire envelope is unwrapped (re-parsing the body when
309+ /// the caller has no parsed envelope at hand), so a subscriber can deserialize the fault as
310+ /// <see cref="Fault{TMessage}"/> of the faulted message type. Publishing is best-effort: a failure to publish
311+ /// the fault is logged and never disrupts settling the original delivery.
309312 /// </summary>
310- private async Task PublishFaultAsync ( Exception ex , BasicDeliverEventArgs ea , IDictionary < string , object ? > headers , string messageTypeName )
313+ private async Task PublishFaultAsync ( Exception ex , BasicDeliverEventArgs ea , IDictionary < string , object ? > headers , MessageEnvelope ? envelope , string messageTypeName )
311314 {
312315 var ( exchange , routingKey ) = ResolveFaultRoute ( headers , _messageConfigurationProvider . FaultExchangeName , messageTypeName ) ;
313316
314317 try
315318 {
316- var originalBody = JsonSerializer . Deserialize < JsonElement > ( ea . Body . Span , _jsonOptions ) ;
319+ var faultedEnvelope = envelope ?? TryParseEnvelope ( ea . Body , _jsonOptions ) ;
320+ var originalMessage = faultedEnvelope ? . Message ?? JsonSerializer . Deserialize < JsonElement > ( ea . Body . Span , _jsonOptions ) ;
317321
318322 var fault = new Fault < JsonElement >
319323 {
320- Message = originalBody ,
324+ Message = originalMessage ,
321325 ExceptionMessage = ex . Message ,
322326 StackTrace = ex . StackTrace ,
323327 ExceptionType = ex . GetType ( ) . FullName ?? "Unknown" ,
0 commit comments