Spring State Machine Error Handling not working

落爺英雄遲暮 提交于 2019-12-11 02:24:33

问题


I did all the setup for error handling

@PostConstruct
public void addStateMachineInterceptor() {
    stateMachine.getStateMachineAccessor().withRegion().addStateMachineInterceptor(interceptor);
    stateMachine.getStateMachineAccessor().doWithRegion(errorinterceptor);
}

created interceptor to handle error:

@Service
public class OrderStateMachineFunction<T> implements StateMachineFunction<StateMachineAccess<String, String>> {
    @Override
    public void apply(StateMachineAccess<String, String> stringStringStateMachineAccess) {
        stringStringStateMachineAccess.addStateMachineInterceptor(
                new StateMachineInterceptorAdapter<String, String>() {
                    @Override
                    public Exception stateMachineError(StateMachine<String, String> stateMachine,
                                                       Exception exception) {
                        // return null indicating handled error
                        return exception;
                    }
                });
    }
}

But I can't see the call going into OrderStateMachineFunction, when we throw the exception from the action.

And after that state machine behave some wired way, like it stops calling preStateChange method after this.stateMachine.sendEvent(eventData);. It seems state machine breaks down after you throw the exception from the action.

    @Service
    public class OrderStateMachineInterceptor extends StateMachineInterceptorAdapter {

        @Override
        public void preStateChange(State newState, Message message, Transition transition, StateMachine stateMachine) {
            System.out.println("Manish");
    }
}

After trying few bit, I have seen that if I comment the resetStateMachine, it works as expected, but without that I am not able to inform the currentstate to state machine:

    public boolean fireEvent(Object data, String previousState, String event) {
        Message<String> eventData = MessageBuilder.withPayload(event)
                .setHeader(DATA_KEY, data)
                .build();
        this.stateMachine.stop();

//        this.stateMachine
//                .getStateMachineAccessor()
//                .withRegion()
//                .resetStateMachine(new DefaultStateMachineContext(previousState, event, eventData.getHeaders(), null));

        this.stateMachine.start();
        return this.stateMachine.sendEvent(eventData);
    }

回答1:


Not sure if you still need this. But I bumped into similar issue. I wanted to propagate exception from state machine to the caller. I implemented StateMachineInterceptor. And inside the state machine transition functions I am setting:

   try
        {
            ..
        }
        catch (WhateverException e)
        {
            stateMachine.setStateMachineError(e);
            throw e;
        }

Then inside the interceptor's stateMachineError method, I have added the Exception in the extendedState map:

public Exception stateMachineError(StateMachine<States, Events> stateMachine, Exception exception)
{ 
stateMachine.getExtendedState().getVariables().put("ERROR", exception);
logger.error("StateMachineError", exception);
return exception;
}

Inside resetStateMachine I have added the interceptor to the statemachine.

a.addStateMachineInterceptor(new LoggingStateMachineInterceptor());

Then when I am calling the sendEvent method, I am doing this:

 if (stateMachine.hasStateMachineError())
        {
            throw (Exception) svtStateMachine.getExtendedState().getVariables().get("ERROR");
        }

This is returning the WhateverException right to the caller. Which in my case is a RestController.



来源:https://stackoverflow.com/questions/37856322/spring-state-machine-error-handling-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!