Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bus failing to publish interface-defined event when messageConstructor not defined #1851

Closed
thirkcircus opened this issue Dec 16, 2013 · 3 comments
Assignees
Labels
Milestone

Comments

@thirkcircus
Copy link
Contributor

When publishing using interface-defined events and when the messageConstructor not defined, an exception is thrown and the event is not published.

I came across an error situation which should have been a lot quicker to identify the root cause.

Using NServiceBus.Core 4.3.0 and NServiceBus.RabbitMQ 3.2.1
I have an event ITestEvent with one property. I'm also using Unobtrusive mode (have been for ages, this isn't a new message type).
If my commandhandler executes the following code it all works as expected:

public override void Handle(TestCommand command)
{
    LogTo.Info("Processing a {0} command...", command.GetType().Name);
    Bus.Publish<ITestEvent>(e => e.TestId = Guid.NewGuid());
}

but if my commandhandler executes the following code (forgetting to specify the messageConstructor for the event):

public override void Handle(TestCommand command)
{
    LogTo.Info("Processing a {0} command...", command.GetType().Name);
    Bus.Publish<ITestEvent>();  // oops, forgot to set the event properties
}

then I get the following error log:

NServiceBus.Unicast.Transport.TransportReceiver - "Failed to process message" with exception 
System.Exception: Could not find Metadata for 'System.Object'.
Please ensure the following:
1. 'System.Object' is included in initial scanning see File Scanning: http://particular.net/articles/the-nservicebus-host
2. 'System.Object' implements either 'IMessage', 'IEvent' or 'ICommand' or alternatively, if you don't want to implement an interface, you can use 'Unobtrusive Mode' see: http://particular.net/articles/unobtrusive-mode-messages
   at NServiceBus.Unicast.Messages.MessageMetadataRegistry.GetMessageDefinition(Type messageType) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\Messages\MessageMetadataRegistry.cs:line 18
   at NServiceBus.Unicast.Messages.LogicalMessageFactory.<CreateMultiple>b__0(Object m) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\Messages\LogicalMessageFactory.cs:line 53
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at NServiceBus.Unicast.Messages.LogicalMessageFactory.CreateMultiple(IEnumerable`1 messages) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\Messages\LogicalMessageFactory.cs:line 48
   at NServiceBus.Unicast.UnicastBus.Publish[T](T[] messages) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 305
   at NServiceBus.Unicast.UnicastBus.Publish[T](T message) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 276
   at NServiceBus.Unicast.UnicastBus.Publish[T](T[] messages) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 295
   at NServiceBus.Unicast.UnicastBus.Publish[T]() in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 284
   at Xero.PostOffice.Test5.TestCommandHandler.Handle(TestCommand command) in c:\Dev\temp\Xero.PostOffice.Test5\Xero.PostOffice.Test5\TestCommandHandler.cs:line 19
   at lambda_method(Closure , Object , Object )
   at NServiceBus.Unicast.HandlerInvocationCache.Invoke(Object handler, Object message, Dictionary`2 dictionary) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\HandlerInvocationCache.cs:line 61
   at NServiceBus.Unicast.HandlerInvocationCache.InvokeHandle(Object handler, Object message) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\HandlerInvocationCache.cs:line 22
   at NServiceBus.Unicast.Behaviors.LoadHandlersBehavior.<Invoke>b__1(Object handlerInstance, Object message) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Unicast\Behaviors\LoadHandlersBehavior.cs:line 38
    SNIP
   at NServiceBus.UnitOfWork.UnitOfWorkBehavior.Invoke(ReceivePhysicalMessageContext context, Action next) in y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\UnitOfWork\UnitOfWorkBehavior.cs:line 20

So two questions:

  1. My ITestEvent should only ever be published when all its properties have been specified - is there a way to enforce this?
  2. Regardless, the error message isn't at all helpful - the error isn't a bad inheritance chain or unobtrusive msg settings, it's that I forgot to set the event properties. The error message is misleading.
@andreasohlund
Copy link
Member

I'd say this is a bug since when you don't pass an action we should just create a new ITestEvent.. But that for some reason gets treated as a Object

@thirkcircus
Copy link
Contributor Author

ok, ta.

when trying to repro, I have:
IEvent (my own marker interface, not the NSB one)
ITestEvent : IEvent
Unobtrusive convention:
config.DefiningCommandsAs(t => typeof(ICommand).IsImplementedBy(t))
.DefiningEventsAs(t => typeof(IEvent).IsImplementedBy(t))
.DefiningMessagesAs(t => typeof(ICommand).IsImplementedBy(t) || typeof(IEvent).IsAssignableFrom(t));

also, what about question 1 - is it possible to enforce all properties are set for a given event before publishing it?
cheers

@andreasohlund
Copy link
Member

also, what about question 1 - is it possible to enforce all properties are
set for a given event before publishing it?

I'd say no, that is in my opinion not something that NSB should get
involved in. Wouldn't this be catched in unit/integration/acceptance tests?

On Tue, Dec 17, 2013 at 4:09 AM, Justin Thirkell
notifications@github.comwrote:

ok, ta.

when trying to repro, I have:
IEvent (my own marker interface, not the NSB one)
ITestEvent : IEvent
Unobtrusive convention:
config.DefiningCommandsAs(t => typeof(ICommand).IsImplementedBy(t))
.DefiningEventsAs(t => typeof(IEvent).IsImplementedBy(t))
.DefiningMessagesAs(t => typeof(ICommand).IsImplementedBy(t) ||
typeof(IEvent).IsAssignableFrom(t));

also, what about question 1 - is it possible to enforce all properties are
set for a given event before publishing it?
cheers


Reply to this email directly or view it on GitHubhttps://github.com//issues/1851#issuecomment-30722920
.

johnsimons pushed a commit that referenced this issue Dec 18, 2013
@ghost ghost assigned johnsimons Dec 18, 2013
@SimonCropp SimonCropp added the Bug label Feb 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants