19. State Machine Error Handling

If state machine detects an internal error during a state transition logic it may throw an exception. Before this exception is processed internally, user is given a chance to intercept.

Normal StateMachineInterceptor can be used to intercept errors and example of it is shown above.

StateMachine<String, String> stateMachine;

void addInterceptor() {
    stateMachine.getStateMachineAccessor()
        .doWithRegion(new StateMachineFunction<StateMachineAccess<String, String>>() {

        @Override
        public void apply(StateMachineAccess<String, String> function) {
            function.addStateMachineInterceptor(
                    new StateMachineInterceptorAdapter<String, String>() {
                @Override
                public Exception stateMachineError(StateMachine<String, String> stateMachine,
                        Exception exception) {
                    // return null indicating handled error
                    return exception;
                }
            });
        }
    });

}

When errors are detected, normal event notify mechanism is executed. This allows to use either StateMachineListener or Spring Application context event listener, more about these read section Chapter 15, Listening State Machine Events.

Having said that, a simple listener would look like:

public static class ErrorStateMachineListener
        extends StateMachineListenerAdapter<String, String> {

    @Override
    public void stateMachineError(StateMachine<String, String> stateMachine, Exception exception) {
        // do something with error
    }
}

Generic ApplicationListener checking StateMachineEvent would look like.

public static class GenericApplicationEventListener
        implements ApplicationListener<StateMachineEvent> {

    @Override
    public void onApplicationEvent(StateMachineEvent event) {
        if (event instanceof OnStateMachineError) {
            // do something with error
        }
    }
}

It’s also possible to define ApplicationListener directly to recognize only StateMachineEvent instances.

public static class ErrorApplicationEventListener
        implements ApplicationListener<OnStateMachineError> {

    @Override
    public void onApplicationEvent(OnStateMachineError event) {
        // do something with error
    }
}