Can the saga context be obtained when implementing the IHandleSagaNotFound


(Steven) #1


When implementing a global handler for IHandleSagaNotFound, is it possible to obtain information on which saga was tried to load?
I have a design where one published message would have to resurrect 2 sagas.
If a saga cannot be found for a reason, I would throw an exception, so the message is retried and eventually sent to the error queue.
In the other case, I would not throw an exception and just “ignore” the message.

One solution could be to redesign those 2 sagas into one.
But that would be my last option.

I was thinking of implementing a behavior that hooks in before the SagaPersistenceBehavior, to store the saga information somewhere, and use that in the SagaNotFoundHandler.

Anyone already implemented such a behavior?
Some pointers are most welcome.


(Andreas Öhlund) #2

Hi Steven, you can get access to the list of saga involved by extending the receive pipeline. ( I’ve cobbled together some code that will get you going)

Add the following 2 behaviors

class SagaTypeRecorder : Behavior<IInvokeHandlerContext>
    public override Task Invoke(IInvokeHandlerContext context, Func<Task> next)
        if(context.MessageHandler.Instance is Saga)
            var sagas = context.Extensions.Get<SagaTypeHolder.SagasInvolved>();


        return next();


class SagaTypeHolder : Behavior<IIncomingPhysicalMessageContext>
    public override Task Invoke(IIncomingPhysicalMessageContext context, Func<Task> next)
        context.Extensions.Set(new SagasInvolved());

        return next();

    public class SagasInvolved
        public List<Type> Sagas = new List<Type>();

and register them:

endpointConfiguration.Pipeline.Register(typeof(SagaTypeHolder), "Holds potential sagas for the incoming message");
endpointConfiguration.Pipeline.Register(typeof(SagaTypeRecorder), "Records potential sagas for the incoming message");

You can then use this in your saga not found handler

    public Task Handle(object message, IMessageProcessingContext context)
        var involvedSagas = context.Extensions.Get<SagaTypeHolder.SagasInvolved>();

        foreach(var sagaType in involvedSagas.Sagas)

        return Task.CompletedTask;

That said, your design sounds a bit funky so perhaps refactoring this into a single saga might be the better long term solution?

(Avinash K C) #3

Hi Andreas Öhlund,
Do you have something that works with NserviceBus v4.4.2, Suggested interfaces are from higher versions I believe.

(Andreas Öhlund) #4

Hi, nothing comes to mind. Unfortunately we didn’t have those types of extension capabilities back then.

Any chance you could upgrade to at least v5?