如何使用弹簧状态机在状态转换期间抛出异常

Dan*_*iel 4 java spring spring-statemachine

我试图理解,在状态转换期间操作引发的异常是如何可能的。我配置了这个简单的状态机:

transitions
    .withExternal()
    .source(State.A1)
    .target(State.A2)
    .event(Event.E1)
    .action(executeAnActionThrowingAnException())
Run Code Online (Sandbox Code Playgroud)

在我的服务类中,我注入了我的状态机并发送了这个事件 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
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的服务中,我只想知道我的状态机是否以及为什么无法到达 State.A2。因为抛出的异常是由 Spring 状态机获取的,所以我在发送事件后无法得到任何响应。但是状态机没有任何错误,这意味着

stateMachine.hasStateMachineError()
Run Code Online (Sandbox Code Playgroud)

将返回假。那么,我怎样才能在我的服务中获取信息,出现问题,更重要的是什么?

我很感激你的帮助。

此致

hov*_*yan 7

对于转换异常,actions 方法有一个重载可用TransitionConfigurer

action(Action<S,E> action, Action<S,E> error)
Run Code Online (Sandbox Code Playgroud)

这意味着如果在转换期间引发异常,您可以指定要触发的其他操作。异常可从StateContext传递给操作中获得。

当您的错误操作被触发时,您可以通过以下方式检索异常:

context.getException();
Run Code Online (Sandbox Code Playgroud)

在错误操作中,您可以做一些事情来处理异常:

  • 记录异常和上下文
  • 转换到某种错误状态
  • 清除上下文并转换到相同状态并尝试执行一些重试逻辑
  • 向上下文添加一些附加信息并将上下文返回给调用者

例如:

context.getVariables().put("hasError", true); 
context.getVariables().put("error", ex);
Run Code Online (Sandbox Code Playgroud)

在您的服务(调用者)中,您可以根据需要处理异常,例如:

public void executeMyLogic() {
    stateMachine.start()
    stateMachine.sendEvent(Event.E1);
    if (stateMachine.getExtendedState().getVariables().containsKey("hasError") {
      throw (RuntimeException)stateMachine.getExtendedState().getVariables().get("error")
    }
}
Run Code Online (Sandbox Code Playgroud)