UnforwardableMessageException while running NServiceBus.Router switch sample

Hello,

I just downloaded the sample from https://docs.particular.net/samples/router/sql-switch/ and I am having trouble running it.
I opened the solution, changed all connection strings to point to my (local) instance instead of SqlExpress and ran the solution.
Other than that, I didn’t change anything and when I send a message using the Blue.Client, the following exception appears in the Switch console:

2019-07-09 16:29:19.991 ERROR Interface Moving poison message to the error queue
NServiceBus.Router.UnforwardableMessageException: No terminator handled the message in the ForwardPublishContext chain. This might indicate a configuration problem. If the message should be dropped, register a chain terminator that explicitly marks that type of messages as handled.
at NServiceBus.Router.TerminatorInvocationRule1.<Invoke>d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() at PublishPreroutingTerminator.<Terminate>d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
at NServiceBus.Router.ChainTerminator1.<Invoke>d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() at NServiceBus.Router.TerminatorInvocationRule1.d__3.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at PreroutingToPublishPreroutingFork.d__0.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult() at NServiceBus.Router.ChainTerminator1.d__1.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at NServiceBus.Router.TerminatorInvocationRule1.<Invoke>d__3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult() at ThrottlingRawEndpointConfig1.<>c__DisplayClass1_0.<b__1>d.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at NServiceBus.Transport.SQLServer.ReceiveStrategy.d__13.MoveNext()
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at NServiceBus.Transport.SQLServer.ProcessWithTransactionScope.d__3.MoveNext()

Only the Green.Billing does not seem to handle the published message.

Am I doing anything wrong?

Thanks for your help!

Hey @s_dargaud, welcome to the Particular Discussion Group!

I’m running into the same error when trying to run this sample. The NServiceBus.Router is a community project and therefore not supported by Particular Software. Maybe @SzymonPobiega can help out with this as he’s the owner of this project (but afaik he’s currently not around).

There seems to be a very similar open issue in the community project repository: https://github.com/SzymonPobiega/NServiceBus.Router/issues/18, can you have a look at that issue and see whether this is the same problem? Otherwise it might be best to create a new issue in the project repository https://github.com/SzymonPobiega/NServiceBus.Router.

Hey!

Thanks for the info. It does seem to be the same issue. I’ll follow the issue on GitHub.

Thanks!

Hey @s_dargaud

The problem you are seeing is caused by an issue with the Router. The issue was caused by the malfunctioning safety mechanism that was meant to detect cases when a message is not forwarded and lost due to a configuration problem. By mistake this mechanism kicked in in cases when there are multiple interfaces and some of them do not have attached subscribers for a given event.

Let’s say there are three brokers and three corresponding interfaces in the router, Red, Green and Blue. If publisher is connected to Red and a subscriber to Blue then the router should route published events from Red to Blue. The thing is, when the router decides which interface to route to, it does not yet know if there is a subscriber on the other side so it passes the message to both interfaces.

In this case Green does not have any subscribers so the pipeline for this interface should drop the message. Here’s where the lost message detection kicks in (while it should not be because the message is not lost).

Version 3.5.1 fixes it by moving the lost message detection code to a place where the pipeline in the incoming interface is in a better position to decide if a message has been lost due to config problem or not.

Sorry for the problems

Szymon

Hey!

Thanks for the update.
In the meantime we realized we could use the Dispatcher instead and are happy with it :slight_smile:

Cheers,
Sebastien