0
votes

I'm new to NServiceBus, so maybe I'm asking something pretty silly here, but is there a way to make NServiceBus not stop sending any messages that are sent in response to a message whose handler fails?

Let me explain with a simple example.

Suppose I have an OrderPaidEvent that has a handler that does the following:

  1. Look for the customer
  2. Start a DB transaction
  3. Update the customer to a good customer
  4. Send an CustomerUpgradedToGoodCustomerEvent message
  5. Commit the DB transaction

Fairly straightforward, all is well in the world. Now a few months later someone else figures that an email would be nice when an order is paid and thus adds another handler to the OrderPaidEvent to send an email.

Unfortunately, now whenever the mailserver has an issue, this second handler will fail with an error which will however prevent the original CustomerUpgradedToGoodCustomerEvent message from being sent (step 4). But because the DB transaction was already committed (step 5) the customer has already been upgraded to a good customer in the database.

This means that even if the OrderPaidEvent handler is retried the customer no longer changes and thus the CustomerUpgradedToGoodCustomerEvent message is never sent. Worse yet, this is all because of a change to the code that has nothing to do with the original message handler and will thus be difficult to detect.

This seems like a massive flaw and since I'm new to this I'm certain there's something I'm doing wrong, but I can't seem to figure out what it is.

Any help from you fine people would be great.

Thanks in advance.

2
Something is off here. What you expect is what NServiceBus does. Feel free to send an email to support at particular dot net and ask for support.Hadi Eskandari
You mean that it doesn't send the message from the first handler or that it doesn't? I've already sent a message to the get-help, address about this, but I haven't heard back yet.Robba
not sure what's the get-help address? Send an email to support at particular dot net. RE the issue, feels like a design flaw in your code. Your email message failing - if designed correctly - has no bearing on your other events/messages.Hadi Eskandari
I'll try that, the get-help address is in the mail 'from' Udi you get when you get an extended license.Robba

2 Answers

2
votes

How about breaking down your procedural code into separate handlers? Thereafter each logical operation will either be done or will not be done based on successful completion of each granular task.

If you add a Saga to the mix then you can make business decisions based on the completed steps in your Saga.

Also maybe read more about transactions and NServiceBus here

0
votes

First of all I would send out the CustomerUpgradedToGoodCustomerEvent after the commit. At that point you are sure that the event actually took place.

And in response to your question: You could handle the email in some 'SendEmail' command that is raised after the db commit and before the event is published. If that command fails it will not hurt the handling of the OrderPaid event. When mail is up again, the command can be retried and handled normally.