diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/listener/CompositeStateMachineListener.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/listener/CompositeStateMachineListener.java index be1aa5e0..6e46f0fa 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/listener/CompositeStateMachineListener.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/listener/CompositeStateMachineListener.java @@ -44,7 +44,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateChanged(from, to); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateChanged", e); } } @@ -56,7 +56,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateEntered(state); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateEntered", e); } } @@ -68,7 +68,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateExited(state); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateExited", e); } } @@ -80,7 +80,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.eventNotAccepted(event); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during eventNotAccepted", e); } } @@ -92,7 +92,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.transition(transition); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during transition", e); } } @@ -104,7 +104,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.transitionStarted(transition); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during transitionStarted", e); } } @@ -116,7 +116,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.transitionEnded(transition); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during transitionEnded", e); } } @@ -128,7 +128,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateMachineStarted(stateMachine); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateMachineStarted", e); } } @@ -140,7 +140,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateMachineStopped(stateMachine); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateMachineStopped", e); } } @@ -152,7 +152,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateMachineError(stateMachine, exception); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateMachineError", e); } } @@ -164,7 +164,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.extendedStateChanged(key, value); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during extendedStateChanged", e); } } @@ -176,7 +176,7 @@ public class CompositeStateMachineListener extends AbstractCompositeListen StateMachineListener listener = iterator.next(); try { listener.stateContext(stateContext); - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during stateContext", e); } } diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/StateMachineObjectSupport.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/StateMachineObjectSupport.java index b4c727d7..984620fd 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/StateMachineObjectSupport.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/StateMachineObjectSupport.java @@ -139,7 +139,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateChanged(this, stateContext.getSource(), stateContext.getTarget()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateChanged", e); } } @@ -155,7 +155,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateEntered(this, stateContext.getTarget()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateEntered", e); } } @@ -171,7 +171,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateExited(this, stateContext.getSource()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateExited", e); } } @@ -187,7 +187,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishEventNotAccepted(this, stateContext.getMessage()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyEventNotAccepted", e); } } @@ -203,7 +203,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishTransitionStart(this, stateContext.getTransition()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyTransitionStart", e); } } @@ -219,7 +219,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishTransition(this, stateContext.getTransition()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyTransition", e); } } @@ -235,7 +235,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishTransitionEnd(this, stateContext.getTransition()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyTransitionEnd", e); } } @@ -251,7 +251,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateMachineStart(this, stateContext.getStateMachine()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateMachineStarted", e); } } @@ -267,7 +267,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateMachineStop(this, stateContext.getStateMachine()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateMachineStopped", e); } } @@ -283,7 +283,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishStateMachineError(this, stateContext.getStateMachine(), stateContext.getException()); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyStateMachineError", e); } } @@ -299,7 +299,7 @@ public abstract class StateMachineObjectSupport extends LifecycleObjectSup eventPublisher.publishExtendedStateChanged(this, key, value); } } - } catch (Exception e) { + } catch (Throwable e) { log.warn("Error during notifyExtendedStateChanged", e); } } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineErrorTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineErrorTests.java index 5e18aa47..4d8f8116 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineErrorTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineErrorTests.java @@ -164,6 +164,28 @@ public class StateMachineErrorTests extends AbstractStateMachineTests { assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2)); } + @Test + public void testListenerErrorsCauseNoMalfunction2() throws Exception { + context.register(EventListenerConfig2.class, Config1.class); + context.refresh(); + + @SuppressWarnings("unchecked") + ObjectStateMachine machine = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); + StartedStateMachineListener listener1 = new StartedStateMachineListener(); + ErroringStateMachineListener2 listener2 = new ErroringStateMachineListener2(); + StateChangedStateMachineListener listener3 = new StateChangedStateMachineListener(); + machine.addStateListener(listener1); + machine.addStateListener(listener2); + + machine.start(); + assertThat(listener1.latch.await(2, TimeUnit.SECONDS), is(true)); + machine.addStateListener(listener3); + machine.sendEvent(TestEvents.E1); + assertThat(listener3.latch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2)); + } + @Configuration @EnableStateMachine static class Config1 extends EnumStateMachineConfigurerAdapter { @@ -391,4 +413,67 @@ public class StateMachineErrorTests extends AbstractStateMachineTests { } } + static class ErroringStateMachineListener2 implements StateMachineListener { + + @Override + public void stateChanged(State from, State to) { + throw new Error(); + } + + @Override + public void stateEntered(State state) { + throw new Error(); + } + + @Override + public void stateExited(State state) { + throw new Error(); + } + + @Override + public void eventNotAccepted(Message event) { + throw new Error(); + } + + @Override + public void transition(Transition transition) { + throw new Error(); + } + + @Override + public void transitionStarted(Transition transition) { + throw new Error(); + } + + @Override + public void transitionEnded(Transition transition) { + throw new Error(); + } + + @Override + public void stateMachineStarted(StateMachine stateMachine) { + throw new Error(); + } + + @Override + public void stateMachineStopped(StateMachine stateMachine) { + throw new Error(); + } + + @Override + public void stateMachineError(StateMachine stateMachine, Exception exception) { + throw new Error(); + } + + @Override + public void extendedStateChanged(Object key, Object value) { + throw new Error(); + } + + @Override + public void stateContext(StateContext stateContext) { + throw new Error(); + } + } + }