SzymonPobiega / NServiceBus.Router

Cross-transport, cross-site and possibly cross-cloud router component for NServiceBus
MIT License
5 stars 10 forks source link

NServiceBus.MessageDeserializationException error #38

Closed eschatzy closed 4 years ago

eschatzy commented 4 years ago

Hi,

I'm getting the following error with multiple command types. The strange this is that it doesn't happen all the time and sometimes I can replay the messages and it works and other times it continues to fail. Note: when not using Routing Bridge these issues don't happen.

We are using the following serializeration: configuration.UseSerialization(); configuration.AddDeserializer();

NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from incoming physical message a14e31b0-a31b-493d-90fc-ac3200432251 ---> System.Exception: Could not determine type for node: 'SetupCheckForDuplicateRecords'. at NServiceBus.XmlDeserialization.InferNodeType(XmlNode node, Object parent) at NServiceBus.XmlDeserialization.Process(XmlNode node, Object parent, Type nodeType) at NServiceBus.XmlDeserialization.Deserialize(Stream stream, IList`1 messageTypesToDeserialize) at NServiceBus.DeserializeMessageConnector.Extract(IncomingMessage physicalMessage) at NServiceBus.DeserializeMessageConnector.ExtractWithExceptionHandling(IncomingMessage message) --- End of inner exception stack trace --- at NServiceBus.DeserializeMessageConnector.ExtractWithExceptionHandling(IncomingMessage message) at NServiceBus.DeserializeMessageConnector.d1.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.SubscriptionReceiverBehavior.d1.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.InvokeAuditPipelineBehavior.d1.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.ProcessingStatisticsBehavior.d0.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 Jitb.NSB.Commons.JitbUnitOfWorkBehavior.d2.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.TransportReceiveToPhysicalMessageConnector.d1.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.MainPipelineExecutor.d1.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.Msmq.ReceiveStrategy.d7.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.Msmq.TransactionScopeStrategy.d__2.MoveNext()

I saw a similar issue (https://discuss.particular.net/t/json-deserialization-error-when-not-using-shared-class-library-for-messages/1702), but that issue was fixed in 3.7.1. I'm currently running 3.8,1.

Thanks, Eric

SzymonPobiega commented 4 years ago

So you get these errors when sending messages between two endpoints over a Router?

when not using Routing Bridge these issues don't happen

You mean NServiceBus.Bridge? Or the NServiceBus.Bridge.Connector package in the endpoint?

eschatzy commented 4 years ago

I'm using the NServiceBus Router two-way bridge topology architecture. Since we are currently testing, we are routing between two existing MSMQ based endpoints.

So you get these errors when sending messages between two endpoints over a Router?

I'm getting these errors in the router queue, between to end points.

You mean NServiceBus.Bridge? Or the NServiceBus.Bridge.Connector package in the endpoint?

I'm using NServiceBus.Bridge.

SzymonPobiega commented 4 years ago

OK, I am now a bit confused. The error you pasted has at NServiceBus.MainPipelineExecutor.d__1.MoveNext() on its stack trace so it definitely happened inside a regular NServiceBus endpoint, not the Router (Router does not have MainPipelineExecutor). Are you able to push the prototype you are working on somewhere to github so that I can pull it and debug?

eschatzy commented 4 years ago

Unfortunately, we are running this in QA with are existing systems. We have almost 50 endpoints that are using multiple Routing Bridge endpoints. These are all separated by business domains.

But I believe I can recreate what we are doing with some type of demo that I can send to you. It will take a little time.

Thanks for you help. Our end goal is to move our endpoints to SQS in a gradual manner, so this is important.

SzymonPobiega commented 4 years ago

In the meantime, what is that SetupCheckForDuplicateRecords node? is that a root node (message type) or some element of a message?

eschatzy commented 4 years ago

This is the SetupCheckForDuplicateRecords class. The IAmNotAudited is a flag type interface: public class SetupCheckForDuplicateRecords : IAmNotAudited { public virtual long MonitorNotificationDateTimeId { get; set; } }

RoutingBridgeDemo.zip

I've attached a demo version of the code. Structurally, it is similar to our code base. I have removed all database persistence. Just run the three endpoints, which will generated 10 commands. Some of the commands will process correct and some may fail.

eschatzy commented 4 years ago

You will need to do a build of the code for it to function.

SzymonPobiega commented 4 years ago

Hi

I built it and it seems to work correct i.e. the DemoCommands get to their destination endpoint. I run it a number of times, same result. That said, the router is now configured to simply "deflect" all messages i.e. whatever comes to it via the msms interface is forwarded via the same interface.

Also, because of the centralized routing configuration you end up sending StartDemo via the router, too. I think you need some sort of logic in the routing config code that would check if the destination is the same as the name of the current endpoint being configured and in that case configure the routing directly i.e. bypassing the router for local messages.

eschatzy commented 4 years ago

So I was able to resolve this issue.

It appears I was registering the Route to Endpoint with RouterConnectionSettings instead of with RoutingSettings. What I found to be strange is that when using RouterConnectionSettings registration was that is actually worked about 60% of the time for the same message type.

I will close this issue, since it is no logger a problem.

SzymonPobiega commented 4 years ago

Sounds like you might have had two competing routes configured somehow but not sure how.