user2330825
user2330825

Reputation: 87

Handling code/configuration error from entry action classes in spring state machine

I am using a state machine builder to build state machine in my app. Also the application has Action classes which implements org.springframework.statemachine.action.Action. These Action classes are for executing entry actions for each stages. If any exception is thrown from these Action classes, ie from execute(StateContext paramStateContext) method, I wanted to catch that exception and send an event(Terminated) and drive the state machine to End state, after updating the db with error details. I tried to use state machine listener by overriding stateMachineError(StateMachine stateMachine, Exception e) method. But unfortunately this is not working. Any other spring state machine component to catch exceptions, before I go to wrap the entire code in Action classes with try catch, and inside catch block sending the Terminated event so that state machine would navigate End state. Here is the builder Iam using.

Builder<String, String> builder = StateMachineBuilder
                .<String, String> builder();
        builder.configureConfiguration()
        .withConfiguration()
        .autoStartup(false)
        .listener(listener())
                .beanFactory(
                this.applicationContext.getAutowireCapableBeanFactory());

private StateMachineListener<String, String> listener() {
        return new StateMachineListenerAdapter<String, String>() {
            @Override
            public void stateChanged(
                    org.springframework.statemachine.state.State<String, String> from,
                    org.springframework.statemachine.state.State<String, String> to) {
                LOGGER.debug("State change to " + to.getId());
            }

            @Override
            public void stateMachineError(
                    StateMachine<String, String> stateMachine, Exception e) {
                e.printStackTrace();
                LOGGER.debug("Ah... I am not getting executed when exception occurs from entry actions");
                LOGGER.debug("Error occured from  " + stateMachine.getState()
                        + "and the error is" + e.toString());
            }
        };
    }

Iam using 1.1.0.RELEASE version of spring-statemachine-core

Upvotes: 0

Views: 1826

Answers (1)

Paul
Paul

Reputation: 20061

You're correct, neither stateMachineError or a method annotated with @onStateMachineError are executed on an error. This is addressed in version 1.2, which is at milestone 1 right now. They introduced errorAction which is executed with the state machine context:

User can always catch exceptions manually but with actions defined for transitions it is possible to define error action which is called if exception is raised. Exception is then available from a StateContext passed to that action.

All that's needed is to specify an error action along with the desired action when defining a transition in the state machine configuration class. From the example in the documentation:

public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
        throws Exception {
    transitions
        .withExternal()
            .source(States.S1)
            .target(States.S2)
            .event(Events.E1)
            .action(action(), errorAction());
}

A detailed discussion of this can be found in Spring Statemachine issue #240.

Upvotes: 0

Related Questions