Skip to content

Unhandled exceptions are not routed to DLQ #3667

@jakoss

Description

@jakoss

Describe the bug

I'm going through the docs here: https://brightercommand.gitbook.io/paramore-brighter-documentation/brighter-request-handlers-and-middleware-pipelines/handlerfailure#terminate-processing-of-that-request

If i understand correctly, when i throw an exception like this:

public class TestEventMessageHandler(ILogger<TestEventMessageHandler> logger) : RequestHandlerAsync<TestEvent>
{
    public override Task<TestEvent> HandleAsync(TestEvent message, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("Test event ({Id}) received with name: {Name}", message.Id, message.Name);
        throw new InvalidOperationException("test");
        return await base.HandleAsync(message, cancellationToken).ConfigureAwait(ContinueOnCapturedContext);
    }
}

The message should be rejected and passed to DLQ. But this is not what i see in the output. Logs are as follows:

info: Paramore.Brighter.MessagingGateway.RMQ.RmqMessageConsumer[0]
      RmqMessageConsumer: Received message from queue TestTopic with routing key TestTopic via exchange TestExternalEventsExchange on subscription amqp://*****@localhost:9994/, message: {"header":{"timeStamp":"2025-07-15T09:25:44Z","id":"d0c13acd-67fb-41e7-afb5-12be5e71aaac","topic":"TestTopic","messageType":"MT_EVENT","bag":{"deliveryTag":1,"redelivered":true},"handledCount":0,"delayedMilliseconds":0,"correlationId":"00000000-0000-0000-0000-000000000000","contentType":"text/plain","replyTo":null,"partitionKey":"","telemetry":null},"body":{"bytes":"eyAibmFtZSIgOiAidGVzdCIgfQ==","contentType":null,"characterEncoding":"UTF8","value":"{ \u0022name\u0022 : \u0022test\u0022 }"},"id":"d0c13acd-67fb-41e7-afb5-12be5e71aaac","deliveryTag":1,"redelivered":true,"persist":true}
info: Paramore.Brighter.CommandProcessor[0]
      Building send async pipeline for event: Test.FacadePlayground.Events.TestEvent 6d1f2d57-49bb-4f12-8842-15f59570b975
info: Paramore.Brighter.CommandProcessor[0]
      Found 1 async pipelines for event: Test.FacadePlayground.Events.TestEvent 6d1f2d57-49bb-4f12-8842-15f59570b975
info: Test.FacadePlayground.Events.TestEventMessageHandler[0]
      Test event (6d1f2d57-49bb-4f12-8842-15f59570b975) received with name: test
fail: Paramore.Brighter.ServiceActivator.MessagePump[0]
      MessagePump: Failed to dispatch message d0c13acd-67fb-41e7-afb5-12be5e71aaac from TestTopic on thread # 19
      System.InvalidOperationException: test
         at Test.FacadePlayground.Events.TestEventMessageHandler.HandleAsync(TestEvent message, CancellationToken cancellationToken) in /Users/jakubsyty/Projects/Test/Test.Backend.Framework/Tests/Test.FacadePlayground/Events/TestEvent.cs:line 16
         at Test.Framework.Messaging.Abstraction.MessageHandler`1.HandleAsync(TMessage command, CancellationToken cancellationToken) in /Users/jakubsyty/Projects/Test/Test.Backend.Framework/Test.Framework.Messaging/Abstraction/MessageHandler.cs:line 12
         at Paramore.Brighter.CommandProcessor.PublishAsync[T](T event, Boolean continueOnCapturedContext, CancellationToken cancellationToken) in /_/src/Paramore.Brighter/CommandProcessor.cs:line 457
info: Paramore.Brighter.MessagingGateway.RMQ.RmqMessageConsumer[0]
      RmqMessageConsumer: Acknowledging message d0c13acd-67fb-41e7-afb5-12be5e71aaac as completed with delivery tag 1

So i dove in to MessagePump code here: https://github.com/BrighterCommand/Brighter/blob/release/9X/src/Paramore.Brighter.ServiceActivator/MessagePump.cs

And the only RejectMessage invocation i can see there is for ConfigurationException. Am i missing something? Should i look at some other place? I want to trace the message coming into my system and why it is not redirected to DLQ. The DLQ settings for exchange and subscriptions are properly set up.

To Reproduce

For now please give me some guidance on where can i trace the message, if i won't be able to track it myself - i'll try to create some repro project.

Further technical details

  • Brighter version - 9.9.10
  • Include the output of dotnet --info
.NET SDK:
 Version:           8.0.411
 Commit:            f97ff31961
 Workload version:  8.0.400-manifests.2ba2f75d
 MSBuild version:   17.11.31+933b72e36

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  15.5
 OS Platform: Darwin
 RID:         osx-arm64
 Base Path:   /usr/local/share/dotnet/sdk/8.0.411/

.NET workloads installed:
Configured to use loose manifests when installing new manifests.
There are no installed workloads to display.

Host:
  Version:      8.0.17
  Architecture: arm64
  Commit:       77545d6fd5

.NET SDKs installed:
  8.0.411 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.17 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.17 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/usr/local/share/dotnet]

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
  • The OS (Window, Linux, MacOs, etc) - MacOs

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions