Skip to content

Commit

Permalink
- *Fixed:* ServiceBusSubscriber was not correctly bubbling (not han…
Browse files Browse the repository at this point in the history
…dling) exceptions where `UnhandledHandling` was set to `ErrorHandling.None`. Was incorrectly treating same as `ErrorHandling.ThrowSubscriberException` and automatically dead-lettering and continuing. (#75)
  • Loading branch information
chullybun authored Sep 8, 2023
1 parent 5d7e1ae commit a37013b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v3.3.1
- *Fixed:* `ServiceBusSubscriber` was not correctly bubbling (not handling) exceptions where `UnhandledHandling` was set to `ErrorHandling.None`. Was incorrectly treating same as `ErrorHandling.ThrowSubscriberException` and automatically dead-lettering and continuing.

## v3.3.0
- *Enhancement:* [Distributed tracing](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-instrumentation-walkthroughs#best-practices) has been added via the `InvokerBase` set of classes throughout `CoreEx` to ensure coverage and consistency of implementation. A new `InvokeArgs` has been added to house the [`ActivitySource`](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.activitysource) instance; this also provides for further extension opportunities limiting future potential breaking changes.

Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.3.0</Version>
<Version>3.3.1</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
4 changes: 4 additions & 0 deletions src/CoreEx.Azure/ServiceBus/ServiceBusSubscriberInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ private static async Task<bool> HandleExceptionAsync(EventSubscriberBase invoker
return true; // Keep throwing; i.e. bubble exception.
}

// Where the unhandled handling is set to None then keep bubbling; do not dead-letter.
if (invoker.UnhandledHandling == Events.Subscribing.ErrorHandling.None)
return true;

// Dead-letter the unhandled exception.
await DeadLetterExceptionAsync(invoker, message, messageActions, ErrorType.UnhandledError.ToString(), exception, cancellationToken).ConfigureAwait(false);
return false;
Expand Down
46 changes: 44 additions & 2 deletions tests/CoreEx.Test/TestFunction/ServiceBusSubsciberTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,61 @@ public async Task Complete()
}

[Test]
public async Task Unhandled_DeadLetter()
public async Task Unhandled_Throw_DeadLetter()
{
using var test = FunctionTester.Create<Startup>();
var actions = test.CreateServiceBusMessageActions();
var message = test.CreateServiceBusMessage(new { id = "A", name = "B", price = 1.99m });

var sbs = test.Services.GetRequiredService<ServiceBusSubscriber>();
sbs.AbandonOnTransient = true;
sbs.UnhandledHandling = Events.Subscribing.ErrorHandling.ThrowSubscriberException;

await sbs.ReceiveAsync(message, actions, (_, _) => throw new DivideByZeroException("Zero is bad dude!"));

actions.AssertRenew(0);
actions.AssertDeadLetter("UnhandledError", "Zero is bad dude!");
}

[Test]
public async Task Unhandled_None_Bubble()
{
using var test = FunctionTester.Create<Startup>();
var actions = test.CreateServiceBusMessageActions();
var message = test.CreateServiceBusMessage(new { id = "A", name = "B", price = 1.99m });

var sbs = test.Services.GetRequiredService<ServiceBusSubscriber>();
sbs.UnhandledHandling = Events.Subscribing.ErrorHandling.None;

try
{
await sbs.ReceiveAsync(message, actions, (_, _) => throw new DivideByZeroException("Zero is bad dude!"));
}
catch (DivideByZeroException)
{
}
catch (Exception ex)
{
Assert.Fail($"Expected {nameof(DivideByZeroException)} but got {ex.GetType().Name}.");
}

actions.AssertRenew(0);
actions.AssertNone();
}

[Test]
public async Task Unhandled_ContinueAsSilent_Complete()
{
using var test = FunctionTester.Create<Startup>();
var actions = test.CreateServiceBusMessageActions();
var message = test.CreateServiceBusMessage(new { id = "A", name = "B", price = 1.99m });

var sbs = test.Services.GetRequiredService<ServiceBusSubscriber>();
sbs.UnhandledHandling = Events.Subscribing.ErrorHandling.CompleteAsSilent;

await sbs.ReceiveAsync(message, actions, (_, _) => throw new DivideByZeroException("Zero is bad dude!"));

actions.AssertRenew(0);
actions.AssertComplete();
}
}
}

0 comments on commit a37013b

Please sign in to comment.