【问题标题】:Spring State Machine Error Handling not workingSpring 状态机错误处理不起作用
【发布时间】:2016-06-16 10:17:37
【问题描述】:

我为错误处理做了所有设置

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

创建拦截器来处理错误:

@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;
                    }
                });
    }
}

但是当我们从操作中抛出异常时,我看不到调用进入 OrderStateMachineFunction。

在该状态机以某种有线方式运行之后,就像它在 this.stateMachine.sendEvent(eventData); 之后停止调用 preStateChange 方法一样。从操作中抛出异常后,状态机似乎崩溃了。

    @Service
    public class OrderStateMachineInterceptor extends StateMachineInterceptorAdapter {

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

在尝试了一些之后,我发现如果我评论 resetStateMachine,它会按预期工作,但没有它我无法将当前状态通知状态机:

    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);
    }

【问题讨论】:

标签: java spring spring-boot spring-statemachine


【解决方案1】:

不确定你是否还需要这个。但我遇到了类似的问题。我想将异常从状态机传播到调用者。我实现了 StateMachineInterceptor。在我设置的状态机转换函数内部:

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

然后在拦截器的 stateMachineError 方法中,我在extendedState 映射中添加了异常:

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

在 resetStateMachine 中,我已将拦截器添加到状态机中。

a.addStateMachineInterceptor(new LoggingStateMachineInterceptor());

然后当我调用 sendEvent 方法时,我正在这样做:

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

这会将 WhatException 权限返回给调用者。在我的例子中是一个 RestController。

【讨论】:

    【解决方案2】:

    我在这里采用的方法是将扩展状态与错误操作相结合来存储错误。

    如果您的操作和其中的任何类发生预期异常,我会将其包含在扩展状态上下文中

    context.getExtendedState().getVariables().put("error", MyBussinessException);
    

    然后,关于我的错误操作(这样配置)

            .withExternal()
            .source(State.INIT)
            .target(State.STARTED)
            .action(action, errorAction)
            .event(Events.INIT)
    

    在机器上下文之外,我总是检查该字段是否存在,并将其转换为正确的响应代码。

    如果动作抛出任何异常,将触发错误动作。在那里您可以检查已知错误(并让它们冒泡),或包含新错误(如果这是意外的话)

    public class ErrorAction implements Action<States, Events> {
    
        @Override
        public void execute(StateContext<States, Events> context) {
           if(!context.getExtendedState().getVariables().containsKey("error")
            context.getExtendedState().getVariables().put("error", new GenericException());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 2018-10-07
      • 2017-04-07
      • 1970-01-01
      • 2018-04-13
      相关资源
      最近更新 更多