async Task ProcessMessage(ServiceBusReceivedMessage message, string messageId, Dictionary <string, string> headers, BinaryData body, CancellationToken messageProcessingCancellationToken) { var contextBag = new ContextBag(); try { using (var transaction = CreateTransaction()) { var transportTransaction = CreateTransportTransaction(message.PartitionKey, transaction); contextBag.Set(message); var messageContext = new MessageContext(messageId, headers, body, transportTransaction, ReceiveAddress, contextBag); await onMessage(messageContext, messageProcessingCancellationToken).ConfigureAwait(false); await receiver.SafeCompleteMessageAsync(message, transportSettings.TransportTransactionMode, transaction, cancellationToken : messageProcessingCancellationToken).ConfigureAwait(false); transaction?.Commit(); } } catch (Exception ex) when(!ex.IsCausedBy(messageProcessingCancellationToken)) { try { ErrorHandleResult result; using (var transaction = CreateTransaction()) { var transportTransaction = CreateTransportTransaction(message.PartitionKey, transaction); var errorContext = new ErrorContext(ex, message.GetNServiceBusHeaders(), messageId, body, transportTransaction, message.DeliveryCount, ReceiveAddress, contextBag); result = await onError(errorContext, messageProcessingCancellationToken).ConfigureAwait(false); if (result == ErrorHandleResult.Handled) { await receiver.SafeCompleteMessageAsync(message, transportSettings.TransportTransactionMode, transaction, cancellationToken : messageProcessingCancellationToken).ConfigureAwait(false); } transaction?.Commit(); } if (result == ErrorHandleResult.RetryRequired) { await receiver.SafeAbandonMessageAsync(message, transportSettings.TransportTransactionMode, cancellationToken : messageProcessingCancellationToken).ConfigureAwait(false); } } catch (ServiceBusException onErrorEx) when(onErrorEx.Reason == ServiceBusFailureReason.MessageLockLost || onErrorEx.Reason == ServiceBusFailureReason.ServiceTimeout) { Logger.Debug("Failed to execute recoverability.", onErrorEx); await receiver.SafeAbandonMessageAsync(message, transportSettings.TransportTransactionMode, cancellationToken : messageProcessingCancellationToken).ConfigureAwait(false); } catch (Exception onErrorEx) when(onErrorEx.IsCausedBy(messageProcessingCancellationToken)) { throw; } catch (Exception onErrorEx) { criticalErrorAction($"Failed to execute recoverability policy for message with native ID: `{message.MessageId}`", onErrorEx, messageProcessingCancellationToken); await receiver.SafeAbandonMessageAsync(message, transportSettings.TransportTransactionMode, cancellationToken : messageProcessingCancellationToken).ConfigureAwait(false); } } }