Handling exceptions occurring in the Event Handler

Hi there,

What is the desired/proposed solution for dealing with exceptions that occur during event handling? Obviously, using a try/catch block does nothing for me as a new thread is spun up and the events are consumed from within the handler.

Is there some kind of listener mechanism that is used to see if an error occurred during processing – in which case you could try to replay the event or at least throw a general exception, stating that a problem occurred while altering the database in the event handler?

Thanks,
Robert

I saw this response in another post – is this still the desired solution?

The CommandBus allows for Interceptors to be configured. Some of these interceptors run in the calling thread, some others in the executing thread. In case of the SimpleCommandBus, the calling thread and executing thread are the same. The main different is that the first type of interceptors is execute before the method returns, allowing them to throw an exception, which is propagated to the caller. This is typically the place where you do structural validation. Your rest API can translate this exception to a 40x error.

As for command handling, when some business rule is violated, you can either throw an exception or use a return value to indicate success/failure. In your rest API, you can deal with this in 2 ways: return immediately giving a 302 while providing a URL where the client can request the result (as soon as it is available). Alternatively, you can wait for the result and return a 200 or 40x depending on the result. Do note that waiting is not always a good thing. When possible, use Servlet 3 async to send the response, as it prevents you from blocking a HTTP thread.

Third option, which could be a little more complex, is to subscribe to the Event Bus for the result of an action. When the result is detected, you return the same way as you would have done using the callback method described earlier (either immediate 302 with request for result, or wait and send a 200/40x).

If you’re planning to use the send-and-wait method, you may want to consider using the CommandGateway concept, as it allows you to easily configure if and how long you want to wait. (See http://www.axonframework.org/docs/2.0/command-handling.html#d4e221).

Hey Robert,

Your post on Command Handler seems good, but it doesn’t deal with your quest (RE: exceptions in Event Handlers.)

The default implementation of the Tracking Event Processor is to retry the event with a exponential backoff strategy (up to 1 minute) on error. With this approach, you shouldn’t implement any behavior that would lead to an exception in the event handler… If an exception does occur, it should be system errors (like database cannot be connected) and waiting for the resource to be available again is a good strategy. If you do not require the message to be received at least once (i.e.: events can be dropped), you can use the LoggingErrorHandler to log-and-forget… Be careful with this as it may lead to inconsistent state. If you want a different behavior, you could override the event processing configuration with a custom listener invocation error handler.

I’m not familiar with subscribing event processors.

Hi Robert and Wayne,

I’d like to add a little extra flavor to this situation.
There are two levels of handling exception in the Event Handling process:

  1. The ListenerInvocationErrorHandler
  2. The ErrorHandler
    Option 1 will be called when it is your @EventHandler annotated function which fails.

The default for this level is the LoggingErrorHandler, which means the failure is logged and the processor will proceed with dealing with the next event.

Option 2 will be called if it’s the internals of the Event Processor which have failed.
The default for this level is the PropagatingErrorHandler, which will propagate an exception further up.

As Wayne added quite nicely, in this situation together with using a Tracking Event Processor, the operation will be retried.

For Subscribing Event Processors paired with exception level two, the exception will just be thrown further up without a retry.
The Subscribing Event Processor isn’t able to recover from this, as it isn’t receiving the events from a persistent location like the Event Store.

That’s my two cents, hope this helps.

Cheers,
Steven

I was thinking of a third option: You can handle the exception with a try-catch within the event handler as well. :slight_smile:

Hi Wayne, Robert,

Wayne, you’re absolutely right.
A simple try-catch block in your own @EventHandler annotated methods would do the trick too.

Cheers,
Steven

Hi there,

On the same subject, is there some way Axon has test facilities to test an eventhandler, which would mimmic an Error while being called by a Tracking Event Processor? In a regular unit test, an Exception will be thrown in a test, but it would be really interesting to assert the event handler behaviour in the context of a TEP calling it and then see the effect of retry procedure and potential error mode.

Regards, Christophe

Hi all,

Christophe, I think your request falls somewhere in the corner of Projection Testing, right?
We have marked an issue to introduce such a feature, as you can find here.

I’ve already heard several requests for this and we are putting it relatively high on our backlog.
Hope this gives some background to the situation!

Cheers,
Steven

Yes, the issue is about a fixture for testing queries/subscription queries.
What I am interested in is testing error handling, but perhaps it fits together… I will add a comment to the ticket.