Why @EndSaga handler failed saga will still end?

Hi,
I was doing some test, then I found that even the @EndSaga annotated handler fails the saga itself will still end.
Is there any reason for this behavior?

Thanks.

https://github.com/AxonFramework/AxonFramework/blob/63d487ab53e11d2fb1b7e45b9edca35e5adc524f/core/src/main/java/org/axonframework/eventhandling/saga/AnnotatedSaga.java#L112

Hi,

in this case, the Saga instance is marked deleted, but if the exception causes the unit of work to rollback, this deletion marker never results in the Saga instance actually being deleted.
What behavior did you exactly observe? Did you check for removal of a Saga in a repository? Or did you use the test fixture to verify for active sagas?

Also note that the @EndSaga is an unconditional end. If you wish to conditionally end the saga, use the SagaLifecycle.end() method instead.

Cheers,

Allard

Hi,
In my case, the saga instance was removed from sagastore (I user JdbcSagastore in my test), thas why I feel it’s counterintuitive.
if it was meant to be rollbacked, why not call doEnd() in the end of try clause instead of calling it in finally clause?

Thanks,

Hi Tian,

a handler throwing an exception does not have to mean a transaction is rolled back. That is configurable behavior.
I just checked to code to see what the default behavior is, and noticed the “suppressExceptions” setting, which defaults to true. This effectively means that exceptions thrown from @SagaEventHandlers are suppressed (and logged) and will not cause the unit of work to roll back.
In other components, we have ErrorHandlers or ListenerInvocationErrorHandlers that allow one to configure what should happen in exceptions. Note that the default here is also to “log and move on”. We are likely to move the SagaManager configuration to this same structure, but it will not change the default behavior.

Any event handlers, but especially Sagas, should cope with any errors they get while interacting with their environment. If necessary, they should schedule retries using an EventScheduler, or at least decide what to do. Relying on infrastructure to just do a redelivery of an event is a dangerous default, as it may cause certain side-effects to be repeatedly executed.

In your case, if you expect exceptions from Sagas to roll back the transaction (which can potentially cause side effects for which the resulting state changes aren’t commited, beware!), you can set “suppressExceptions” to false.

Cheers,

Allard

Hi,
It seems “suppressExceptions” is hard to set, or it’s me just don’t know the proper way of doing it.

  1. SagaConfiguration don’t have this opiton.
  2. SagaConfiguration’s constructor is private.
  3. can’t call getSagaManager().setSuppressExceptions(false) in the configuring phase, otherwise will got “Configuration is not initialized yet”

I totally agree that sagas should handle exceptions properly. But I’m a bit worried sometimes someone didn’t handle exceptions and the saga instance was removed from saga store, It’s might be hard to recover those data.

Thanks,

Hi Tian,

your comment is noted (as issue 447). We will improve the configuration API for the 3.2 version.

The reason you’re getting the exception, is that the configuration hasn’t been completely initialized, yet. These components are only accessible when that happened.
A workaround is to inject both the SagaConfiguration and the (Axon)Configuration beans, and use
axonConfiguration.onStart(() -> sagaConfiguration.getSagaManager().setSuppressExceptions(true));
That should perform the change at the right time.

Cheers,

Allard

Thanks, it there any ETA for 3.2 ?

Hi Tian,

we have no ETA, yet. We hope to be delivering versions a bit faster than it took us to get 3.1 out. Somewhere early Feb is probably realistic.

Allard

Hi Allard,
It seems “suppressExceptions” won’t matter because doEnd was called in finally clause. so no matter suppressExceptions or not, the sagaentry will always be deleted.
Shouldn’t doEnd be called in try clause?

} finally {if (h.isEndingHandler()) {doEnd();}}
https://github.com/AxonFramework/AxonFramework/blob/63d487ab53e11d2fb1b7e45b9edca35e5adc524f/core/src/main/java/org/axonframework/eventhandling/saga/AnnotatedSaga.java#L112