Skip to content

Commit

Permalink
Move ErrorHandlerMiddleware down next to HandlerInvocationMiddleware,…
Browse files Browse the repository at this point in the history
… and ensure exceptions are logged (#1023)

* - Add HandleMessageContext.HandledException to log context so handler failures can be explained

* - Move ErrorHandler middleware next to handler invocation middleware in default setup so that it handles errors as a first priority.

LoggingMiddleware assumes a handled exception is available in the context, as should others, instead of handling and rethrowing themselves.

* - Update doc comments that list middleware order

* - Check exception not null before checking the message

Co-authored-by: George Kinsman <george.kinsman@justeattakeaway.com>
  • Loading branch information
gkinsman and George Kinsman committed Jun 9, 2022
1 parent 5bff12e commit a6aaca6
Show file tree
Hide file tree
Showing 10 changed files with 22 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/JustSaying/Fluent/ISubscriptionBuilder`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ public interface ISubscriptionBuilder<out T>
/// <li>Before_SomeCustomMiddleware</li>
/// <li>Before_SomeOtherCustomMiddleware</li>
/// <li>Before_MessageContextAccessorMiddleware</li>
/// <li>Before_ErrorHandlerMiddleware</li>
/// <li>Before_LoggingMiddleware</li>
/// <li>Before_StopwatchMiddleware</li>
/// <li>Before_SqsPostProcessorMiddleware</li>
/// <li>Before_ErrorHandlerMiddleware</li>
/// <li>Before_HandlerInvocationMiddleware</li>
/// <li>After_HandlerInvocationMiddleware</li>
/// <li>After_ErrorHandlerMiddleware</li>
/// <li>After_SqsPostProcessorMiddleware</li>
/// <li>After_StopwatchMiddleware</li>
/// <li>After_LoggingMiddleware</li>
/// <li>After_ErrorHandlerMiddleware</li>
/// <li>After_MessageContextAccessorMiddleware</li>
/// <li>After_SomeOtherCustomMiddleware</li>
/// <li>After_SomeCustomMiddleware</li>
Expand All @@ -72,4 +72,4 @@ public interface ISubscriptionBuilder<out T>
IVerifyAmazonQueues creator,
IAwsClientFactoryProxy awsClientFactoryProxy,
ILoggerFactory loggerFactory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ public static class HandlerMiddlewareBuilderExtensions
/// <summary>
/// <para>
/// Applies a set of default middlewares in order. Adding other middlewares before this will add them
/// to the top of the stack, and are run first and last.
/// to the top of the stack, and are run first to last.
/// Adding other middleware after this will add them to the bottom of the stack, just before the
/// handler itself is invoked.
/// </para>
/// The middlewares this adds are, in order:
/// <list type="bullet">
/// <item>MessageContextAccessorMiddleware</item>
/// <item>BackoffMiddleware (only if an <see cref="IMessageBackoffStrategy"/> is available)</item>
/// <item>ErrorHandlerMiddleware</item>
/// <item>LoggingMiddleware</item>
/// <item>StopwatchMiddleware</item>
/// <item>SqsPostProcessorMiddleware</item>
/// <item>ErrorHandlerMiddleware</item>
/// <item>HandlerInvocationMiddleware`1</item>
/// </list>
/// </summary>
Expand All @@ -65,12 +65,12 @@ public static class HandlerMiddlewareBuilderExtensions
if (handlerType == null) throw new ArgumentNullException(nameof(handlerType), "HandlerType is used here to");

builder.UseMessageContextAccessor();
builder.UseErrorHandler();
builder.Use<LoggingMiddleware>();
builder.UseStopwatch(handlerType);
builder.Use<SqsPostProcessorMiddleware>();
builder.UseErrorHandler();
builder.UseHandler<TMessage>();

return builder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ protected override async Task<bool> RunInnerAsync(HandleMessageContext context,
{
if (dispatchSuccessful)
{
_logger.LogInformation(MessageTemplate,
_logger.LogInformation(context.HandledException, MessageTemplate,
Succeeded,
context.Message.Id,
context.MessageType.FullName,
watch.ElapsedMilliseconds);
}
else
{
_logger.LogWarning(MessageTemplate,
_logger.LogWarning(context.HandledException, MessageTemplate,
Failed,
context.Message.Id,
context.MessageType.FullName,
watch.ElapsedMilliseconds);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"QueueName": "beforequeue-simplemessage-afterqueue",
"MiddlewareChain": [
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"QueueName": "integrationTestQueueName",
"MiddlewareChain": [
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"QueueName": "integrationTestQueueName",
"MiddlewareChain": [
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"WhenApplyingDefaultMiddlewares+OuterTestMiddleware",
"WhenApplyingDefaultMiddlewares+InnerTestMiddleware",
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"WhenApplyingDefaultMiddlewares+AfterTestMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"QueueName": "TestQueueName",
"MiddlewareChain": [
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
"MiddlewareChain": [
"ExactlyOnceMiddleware`1[JustSaying.TestingFramework.SimpleMessage]",
"MessageContextAccessorMiddleware",
"ErrorHandlerMiddleware",
"LoggingMiddleware",
"StopwatchMiddleware",
"SqsPostProcessorMiddleware",
"ErrorHandlerMiddleware",
"HandlerInvocationMiddleware`1[JustSaying.TestingFramework.SimpleMessage]"
]
}
Expand Down
7 changes: 6 additions & 1 deletion tests/JustSaying.IntegrationTests/Logging/LogContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,12 @@ public async Task HandleMessageFromQueueLogs_ShouldHaveContext(bool handlerShoul
handleMessage.ShouldNotBeNull();
handleMessage.LogLevel.ShouldBe(level);
handleMessage.Exception?.Message.ShouldBe(exceptionMessage);
if (exceptionMessage != null)
{
handleMessage.Exception.ShouldNotBeNull();
handleMessage.Exception.Message.ShouldBe(exceptionMessage);
}
var propertyMap = new Dictionary<string, object>(handleMessage.Properties);
propertyMap.ShouldContainKeyAndValue("Status", status);
Expand Down

0 comments on commit a6aaca6

Please sign in to comment.