问题
I am trying to understand, how an exception thrown by an action during a state transition is possible. I‘ve this simple state machine configured:
transitions
.withExternal()
.source(State.A1)
.target(State.A2)
.event(Event.E1)
.action(executeAnActionThrowingAnException())
In my service class, I injected my state machine and send this event E1:
@Service
public class MyService() {
@Autowired
private StateMachine<State, Event> stateMachine;
public void executeMyLogic() {
stateMachine.start()
stateMachine.sendEvent(Event.E1);
// how to get thrown exception here
}
}
In my service I just want to know, if and why my state machine wasn‘t able to reached State.A2. Because a thrown exception is fetched by Spring state machine, I am not able to get any response after sending the event. But the state machine hasn‘t any error, which means that
stateMachine.hasStateMachineError()
will return false. So, how can I get the information in my service, that something went wrong and more importantly what?
I appriciate your help.
Best regards
回答1:
For transitions exceptions, there's an overload for the actions method available in the TransitionConfigurer
action(Action<S,E> action, Action<S,E> error)
This means you can specify and additional action to be triggered, if there's an exception raised during the transition. The exception is available from the StateContext
passed to the action.
When your error action is triggered, you can retrieve the exception with:
context.getException();
Inside the error action you can do a couple of things to deal with the exception:
- do logging of the exception and the context
- transition to some error state
- clear the context and transition to the same state and try to execute some retry logic
- add some additional info to the context and return the context to the caller
For example:
context.getVariables().put("hasError", true);
context.getVariables().put("error", ex);
And in your service(caller) you handle the exception as you like, for example:
public void executeMyLogic() {
stateMachine.start()
stateMachine.sendEvent(Event.E1);
if (stateMachine.getExtendedState().getVariables().containsKey("hasError") {
throw (RuntimeException)stateMachine.getExtendedState().getVariables().get("error")
}
}
来源:https://stackoverflow.com/questions/55047384/how-to-get-exception-thrown-during-state-transition-using-spring-state-machine