A colleague of mine was discussing my blog post “Routing exceptions on send ports to the ESB Exception Management Portal without turning on routing for failed messages (Part 1)” with me since he wanted to implement the pattern on his own project, but he wanted to take this a bit further. He wanted for the generation of NACKs on ports to be set at run time rather than design time so that the exception handling was a bit more global and enabling exception handling for a send port becomes more of an administration task than a development task. We managed to best the challenge with surprising ease and I thought it was time to write a second part to the aforementioned blog post.
In the solution mentioned in the previous blog post, the subscriptions for NACK messages from specific send ports were generated based on orchestration activation filters and thus obviously can’t be changed at run time as these are design time properties only. The next best alternative was to look at processing NACKs by adjusting the ALL.Exceptions send port in the Microsoft.Practices.ESB application or a similar send port. We thought that at the very least we were going to have to write some custom pipeline components to extract the error details from our NACK message and write them to the ErrorType and other relevant context properties for the ESB Pipeline Components to process appropriately.
The big surprise was to find out that the ESB Exception Encoder pipeline component was written with NACK messages in mind as well (if you use Reflector on the assembly this will be very quickly apparent), and will process them with no extra effort whatsoever. In the below screenshot you’ll see that the ALL.Exceptions send port has had its filter criteria adjusted such that it now subscribes to NACK messages from SendPort1 and SendPort2 in addition to its existing filters thus prompting those send ports to start generating NACKs which will get sent to the ESB Exception database with no orchestration.
Adding more send ports to this list is something that can easily be done at run time and thus requires no development effort. Below is a side by side comparison of NACK errors in the ESB Portal, the error on the left being generated by a send port as described in this article and the error on the right being generated by an orchestration as described in the previous blog post.
The first huge benefit is that while for the orchestration generated error the Service Instance ID is for the orchestration that threw the exception and the Service Instance ID of the suspended send port has to be found in the Fault Description, the Service Instance ID listed for the Send Port generated error is the correct one for the send port that has been suspended. This removes a fair bit of confusion.
It is also quite nice that the send port name is listed under service name rather than the exception handling orchestrations name, and it is also quite nice to see the endpoint URL in the Application Scope rather than whatever value you set it to in the orchestration. The exception type, error type, and machine name are always set to unknown for the send port generated errors. While this might be seen as less friendly than the orchestration generated errors one has to remember that the machine name listed for the orchestration generated errors was the machine name on which the exception handling orchestration was executed rather than on which the now suspended send port instance was executed. If one was really keen they could write a pipeline component that replaces the values unknown with whatever else they wanted after the ESB pipeline components have finished executing but I’m not sure how much value this could really add.
I think this is a cleaner solution than the one I blogged about previously, and while that one has its place in specific scenarios I think this one will be my default position from here on out.