From 012f54fd3cc529ccba888c30542330d30ae70274 Mon Sep 17 00:00:00 2001 From: Alexander Hjalmarsson Date: Thu, 19 Jun 2025 13:33:39 +0200 Subject: [PATCH 1/2] DefaultRetryStep failure handling moved to before processing message to avoid nested scope abortion for usage with transactionscope + transports enlisting in ambient transaction --- Rebus/Retry/Simple/DefaultRetryStep.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Rebus/Retry/Simple/DefaultRetryStep.cs b/Rebus/Retry/Simple/DefaultRetryStep.cs index 9616198be..912912b4e 100644 --- a/Rebus/Retry/Simple/DefaultRetryStep.cs +++ b/Rebus/Retry/Simple/DefaultRetryStep.cs @@ -100,6 +100,16 @@ await PassToErrorHandler(context, _exceptionInfoFactory.CreateInfo(new RebusAppl } } + if (await _errorTracker.HasFailedTooManyTimes(messageId)) + { + var aggregateException = GetAggregateException(await _errorTracker.GetExceptions(messageId)); + + await PassToErrorHandler(context, aggregateException); + await _errorTracker.CleanUp(messageId); + transactionContext.SetResult(commit: false, ack: true); + return; + } + try { await next(); @@ -157,11 +167,7 @@ async Task HandleException(Exception exception, ITransactionContext transactionC return; } - var aggregateException = GetAggregateException(await _errorTracker.GetExceptions(messageId)); - - await PassToErrorHandler(context, aggregateException); - await _errorTracker.CleanUp(messageId); - transactionContext.SetResult(commit: false, ack: true); + transactionContext.SetResult(commit: false, ack: false); } async Task DispatchSecondLevelRetry(ITransactionContext transactionContext, string messageId, IncomingStepContext context, Func next) From 463ec9d7e0c0823abab4a93ed0ce029c362411ed Mon Sep 17 00:00:00 2001 From: Alexander Hjalmarsson Date: Thu, 19 Jun 2025 21:38:21 +0200 Subject: [PATCH 2/2] Moved the secondlevelretries-logic and sismplified the exception method --- .../Retry/Simple/TestDefaultRetryStep.cs | 6 +++--- Rebus/Retry/Simple/DefaultRetryStep.cs | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Rebus.Tests/Retry/Simple/TestDefaultRetryStep.cs b/Rebus.Tests/Retry/Simple/TestDefaultRetryStep.cs index cc72fcbaf..4602686a8 100644 --- a/Rebus.Tests/Retry/Simple/TestDefaultRetryStep.cs +++ b/Rebus.Tests/Retry/Simple/TestDefaultRetryStep.cs @@ -52,7 +52,7 @@ public async Task CreatesInfoForSecondLevelRetryException( Mock exceptionInfoFactory, IncomingStepContext context, TransportMessage message, string id, - Exception[] nextExceptions) + Exception nextException) { failFastChecker.Setup(ffc => ffc.ShouldFailFast(It.IsAny(), It.IsAny())).Returns(false); errorTracker.Setup(et => et.HasFailedTooManyTimes(It.IsAny())).ReturnsAsync(true); @@ -61,8 +61,8 @@ public async Task CreatesInfoForSecondLevelRetryException( context.Save(message); int i = 0; - await step.Process(context, () => throw nextExceptions[i++]); + await step.Process(context, () => throw nextException); - exceptionInfoFactory.Verify(eif => eif.CreateInfo(nextExceptions[1])); + exceptionInfoFactory.Verify(eif => eif.CreateInfo(nextException)); } } \ No newline at end of file diff --git a/Rebus/Retry/Simple/DefaultRetryStep.cs b/Rebus/Retry/Simple/DefaultRetryStep.cs index 912912b4e..29f67fd2b 100644 --- a/Rebus/Retry/Simple/DefaultRetryStep.cs +++ b/Rebus/Retry/Simple/DefaultRetryStep.cs @@ -102,6 +102,12 @@ await PassToErrorHandler(context, _exceptionInfoFactory.CreateInfo(new RebusAppl if (await _errorTracker.HasFailedTooManyTimes(messageId)) { + if (_retryStrategySettings.SecondLevelRetriesEnabled) + { + await DispatchSecondLevelRetry(transactionContext, messageId, context, next); + return; + } + var aggregateException = GetAggregateException(await _errorTracker.GetExceptions(messageId)); await PassToErrorHandler(context, aggregateException); @@ -155,18 +161,6 @@ async Task HandleException(Exception exception, ITransactionContext transactionC await _errorTracker.RegisterError(messageId, exception); - if (!await _errorTracker.HasFailedTooManyTimes(messageId)) - { - transactionContext.SetResult(commit: false, ack: false); - return; - } - - if (_retryStrategySettings.SecondLevelRetriesEnabled) - { - await DispatchSecondLevelRetry(transactionContext, messageId, context, next); - return; - } - transactionContext.SetResult(commit: false, ack: false); }