diff --git a/src/Transport/Receiving/MessagePump.cs b/src/Transport/Receiving/MessagePump.cs index c8ba86ef..b5c98efd 100644 --- a/src/Transport/Receiving/MessagePump.cs +++ b/src/Transport/Receiving/MessagePump.cs @@ -243,6 +243,10 @@ async Task ProcessMessage(Task receiveTask) await receiver.SafeAbandonAsync(pushSettings.RequiredTransactionMode, lockToken).ConfigureAwait(false); } } + catch (Exception onErrorException) when (onErrorException is MessageLockLostException || onErrorException is ServiceBusTimeoutException) + { + logger.Debug("Failed to execute recoverability.", onErrorException); + } catch (Exception onErrorException) { criticalError.Raise($"Failed to execute recoverability policy for message with native ID: `{message.MessageId}`", onErrorException); diff --git a/src/TransportTests/When_MessageLockLostException_is_thrown.cs b/src/TransportTests/When_MessageLockLostException_is_thrown.cs new file mode 100644 index 00000000..c8e4596e --- /dev/null +++ b/src/TransportTests/When_MessageLockLostException_is_thrown.cs @@ -0,0 +1,54 @@ +namespace NServiceBus.Transport.AzureServiceBus.TransportTests +{ + using System.Threading.Tasks; + using Microsoft.Azure.ServiceBus; + using NServiceBus.TransportTests; + using NUnit.Framework; + + [TestFixture] + public class When_MessageLockLostException_is_thrown : NServiceBusTransportTest + { + [TestCase(TransportTransactionMode.None)] + [TestCase(TransportTransactionMode.ReceiveOnly)] + [TestCase(TransportTransactionMode.SendsAtomicWithReceive)] + public async Task Should_not_raise_critical_error(TransportTransactionMode transactionMode) + { + var criticalErrorInvoked = new TaskCompletionSource(); + var criticalErrorCalled = false; + + OnTestTimeout(() => criticalErrorInvoked.SetResult(false)); + + var firstInvocation = true; + + await StartPump( + context => + { + if (firstInvocation) + { + firstInvocation = false; + throw new MessageLockLostException("from onMessage"); + } + + return Task.CompletedTask; + }, + context => + { + throw new MessageLockLostException("from onError"); + }, + transactionMode, + (message, exception) => + { + criticalErrorCalled = true; + criticalErrorInvoked.SetResult(true); + } + ); + + await SendMessage(InputQueueName); + + await criticalErrorInvoked.Task; + + Assert.IsFalse(criticalErrorCalled, $"Should not invoke critical error for {nameof(MessageLockLostException)}"); + Assert.IsFalse(criticalErrorInvoked.Task.Result); + } + } +} \ No newline at end of file diff --git a/src/TransportTests/When_ServiceBusTimeoutException_is_thrown.cs b/src/TransportTests/When_ServiceBusTimeoutException_is_thrown.cs new file mode 100644 index 00000000..1a19b571 --- /dev/null +++ b/src/TransportTests/When_ServiceBusTimeoutException_is_thrown.cs @@ -0,0 +1,54 @@ +namespace NServiceBus.Transport.AzureServiceBus.TransportTests +{ + using System.Threading.Tasks; + using Microsoft.Azure.ServiceBus; + using NServiceBus.TransportTests; + using NUnit.Framework; + + [TestFixture] + public class When_ServiceBusTimeoutException_is_thrown : NServiceBusTransportTest + { + [TestCase(TransportTransactionMode.None)] + [TestCase(TransportTransactionMode.ReceiveOnly)] + [TestCase(TransportTransactionMode.SendsAtomicWithReceive)] + public async Task Should_not_raise_critical_error(TransportTransactionMode transactionMode) + { + var criticalErrorInvoked = new TaskCompletionSource(); + var criticalErrorCalled = false; + + OnTestTimeout(() => criticalErrorInvoked.SetResult(false)); + + var firstInvocation = true; + + await StartPump( + context => + { + if (firstInvocation) + { + firstInvocation = false; + throw new ServiceBusTimeoutException("from onMessage"); + } + + return Task.CompletedTask; + }, + context => + { + throw new ServiceBusTimeoutException("from onError"); + }, + transactionMode, + (message, exception) => + { + criticalErrorCalled = true; + criticalErrorInvoked.SetResult(true); + } + ); + + await SendMessage(InputQueueName); + + await criticalErrorInvoked.Task; + + Assert.IsFalse(criticalErrorCalled, $"Should not invoke critical error for {nameof(ServiceBusTimeoutException)}"); + Assert.IsFalse(criticalErrorInvoked.Task.Result); + } + } +} \ No newline at end of file