Skip to content

The search box in the website knows all the secrets—try it!

For any queries, join our Discord Channel to reach us faster.

JasperFx Logo

JasperFx provides formal support for Wolverine and other JasperFx libraries. Please check our Support Plans for more details.

Unknown Messages

When Wolverine receives a message from the outside world, it's keying off the message type name from the Envelope to "know" what message type it's receiving and therefore, which handler(s) to execute. It's an imperfect world of course, so it's perfectly possible that your system will receive a message from the outside world with a message type name that your system does not recognize.

Out of the box Wolverine will simply log that it received an unknown message type and discard the message, but there are means to take additional actions on "missing handler" messages where Wolverine does not recognize the message type.

Move to the Dead Letter Queue 5.3

You can declaratively tell Wolverine to persist every message received with an unknown message type name to the dead letter queue with this flag:

cs
var builder = Host.CreateApplicationBuilder();
builder.UseWolverine(opts =>
{
    var connectionString = builder.Configuration.GetConnectionString("rabbit");
    opts.UseRabbitMq(connectionString).UseConventionalRouting();

    // All unknown message types received should be placed into 
    // the proper dead letter queue mechanism
    opts.UnknownMessageBehavior = UnknownMessageBehavior.DeadLetterQueue;
});

snippet source | anchor

The message will be moved to the dead letter queue mechanism for the listening endpoint where the message was received.

Custom Actions

::: note The missing handlers are additive, meaning that you can provide more than one and Wolverine will try to execute each one that is registered for the missing handler behavior. :::

You can direct Wolverine to take custom actions on messages received with unknown message type names by providing a custom implementation of this interface:

cs
namespace Wolverine;

/// <summary>
///     Hook interface to receive notifications of envelopes received
///     that do not match any known handlers within the system
/// </summary>
public interface IMissingHandler
{
    /// <summary>
    ///     Executes for unhandled envelopes
    /// </summary>
    /// <param name="context"></param>
    /// <param name="root"></param>
    /// <returns></returns>
    ValueTask HandleAsync(IEnvelopeLifecycle context, IWolverineRuntime root);
}

snippet source | anchor

Here's a made up sample that theoretically posts a message to a Slack room by sending a Wolverine message in response:

cs
public class MyCustomActionForMissingHandlers : IMissingHandler
{
    public ValueTask HandleAsync(IEnvelopeLifecycle context, IWolverineRuntime root)
    {
        var bus = new MessageBus(root);
        return bus.PublishAsync(new PostInSlack("Incidents",
            $"Got an unknown message with type '{context.Envelope.MessageType}' and id {context.Envelope.Id}"));
    }
}

snippet source | anchor

And simply registering that with your application's IoC container against the IMissingHandler interface like this:

cs
var builder = Host.CreateApplicationBuilder();
builder.UseWolverine(opts =>
{
    // configuration
    opts.UnknownMessageBehavior = UnknownMessageBehavior.DeadLetterQueue;
});

builder.Services.AddSingleton<IMissingHandler, MyCustomActionForMissingHandlers>();

snippet source | anchor

Tracked Session Testing

Just know that the Tracked Session subsystem for integration testing exposes a separate record collection for NoHandlers and reports when that happens through its output for hopefully easy troubleshooting on test failures.

Released under the MIT License.