spring-projects / spring-statemachine

Spring Statemachine is a framework for application developers to use state machine concepts with Spring.
1.52k stars 598 forks source link

how to error handling in StateMachineInterceptorAdapter override method preStateChange #1090

Open pasudo123 opened 1 year ago

pasudo123 commented 1 year ago

Hello!

i wrote code below! with kotlin lang. i'm used preStateChange() method by implements StateMachineInterceptorAdapter<S, E> class

@Transactional
    override fun preStateChange(
        state: State<Product.Status, Product.Event>?,
        message: Message<Product.Event>?,
        transition: Transition<Product.Status, Product.Event>?,
        stateMachine: StateMachine<Product.Status, Product.Event>?,
        rootStateMachine: StateMachine<Product.Status, Product.Event>?
    ) {

        if (state.isNull()) {
            log.info("@@@ preStateChanged : state is null")
            return
        }

        log.info("@@@ preStateChanged : state.id[${state!!.id}]")

        throw RuntimeException("oops?!")
    }

i want to try/catch in preStateChange() method if throw exception

but looking at the preStateChange method does not throw and did logging and return false (boolean type)

AbstractStateMachine.java

    private boolean callPreStateChangeInterceptors(State<S,E> state, Message<E> message, Transition<S,E> transition, StateMachine<S, E> stateMachine) {
        try {
            getStateMachineInterceptors().preStateChange(state, message, transition, this, stateMachine);
        } catch (Exception e) {
            log.info("Interceptors threw exception, skipping state change", e);
            return false;
        }
        return true;
    }

// if callPreStateChangeInterceptors() method return false and switchToState() method return Mono.empty()
private Mono<Void> switchToState(State<S,E> state, Message<E> message, Transition<S,E> transition, StateMachine<S, E> stateMachine) {
        return Mono.defer(() -> {
            if (!isInitialTransition(transition) && !StateMachineUtils.isTransientPseudoState(state)
                    && !callPreStateChangeInterceptors(state, message, transition, stateMachine)) {
                return Mono.empty();
            }

can I get some help with that? (i using 3.2.0 version)

jchbh-duplicate commented 7 months ago

Had the same problem, Based on document, throw exception in Interceptor should stop the transaction but actually it doesn't when the transaction is happened to a Pseudo State, such as choice.