2323from collections import deque
2424from functools import partial , reduce
2525import copy
26+ from concurrent .futures import CancelledError
2627
2728from ..core import State , Condition , Transition , EventData , listify
2829from ..core import Event , MachineError , Machine
@@ -197,20 +198,25 @@ async def _trigger(self, event_data):
197198 except BaseException as err : # pylint: disable=broad-except; Exception will be handled elsewhere
198199 _LOGGER .error ("%sException was raised while processing the trigger '%s': %s" ,
199200 self .machine .name , event_data .event .name , repr (err ))
200- event_data .error = err
201+ event_data .error = err if isinstance (err ,Exception ) else CancelledError ()
202+
201203 if self .machine .on_exception :
202- await self .machine .callbacks (self .machine .on_exception , event_data )
203- else :
204+ with anyio .move_on_after (2 , shield = True ):
205+ await self .machine .callbacks (self .machine .on_exception , event_data )
206+ if not self .machine .on_exception or not isinstance (err , Exception ):
204207 raise
205208 finally :
206209 try :
207- await self .machine .callbacks (self .machine .finalize_event , event_data )
210+ with anyio .CancelScope (shield = True ):
211+ await self .machine .callbacks (self .machine .finalize_event , event_data )
208212 _LOGGER .debug ("%sExecuted machine finalize callbacks" , self .machine .name )
209213 except BaseException as err : # pylint: disable=broad-except; Exception will be handled elsewhere
210214 _LOGGER .error ("%sWhile executing finalize callbacks a %s occurred: %s." ,
211215 self .machine .name ,
212216 type (err ).__name__ ,
213217 str (err ))
218+ if not isinstance (err , Exception ):
219+ raise
214220 return event_data .result
215221
216222 async def _process (self , event_data ):
@@ -481,7 +487,7 @@ async def _can_trigger(self, model, trigger, *args, **kwargs):
481487 event_data .error = err
482488 if self .on_exception :
483489 await self .callbacks (self .on_exception , event_data )
484- else :
490+ if not self . on_exception or not isinstance ( err , Exception ) :
485491 raise
486492 return False
487493
@@ -556,7 +562,7 @@ async def _trigger_event(self, event_data, trigger):
556562 event_data .error = err
557563 if self .on_exception :
558564 await self .callbacks (self .on_exception , event_data )
559- else :
565+ if not self . on_exception or not isinstance ( err , Exception ) :
560566 raise
561567 finally :
562568 try :
@@ -567,6 +573,8 @@ async def _trigger_event(self, event_data, trigger):
567573 self .name ,
568574 type (err ).__name__ ,
569575 str (err ))
576+ if not isinstance (err , Exception ):
577+ raise
570578 return event_data .result
571579
572580 async def _trigger_event_nested (self , event_data , _trigger , _state_tree ):
@@ -616,7 +624,7 @@ async def _can_trigger_nested(self, model, trigger, path, *args, **kwargs):
616624 event_data .error = err
617625 if self .on_exception :
618626 await self .callbacks (self .on_exception , event_data )
619- else :
627+ if not self . on_exception or not isinstance ( err , Exception ) :
620628 raise
621629 source_path .pop (- 1 )
622630 if path :
@@ -711,16 +719,19 @@ async def _process_timeout(self, event_data):
711719 except BaseException as err :
712720 _LOGGER .warning ("%sException raised while processing timeout!" ,
713721 event_data .machine .name )
714- event_data .error = err
722+ event_data .error = err if isinstance ( err , Exception ) else CancelledError ()
715723 try :
716724 if event_data .machine .on_exception :
717725 await event_data .machine .callbacks (event_data .machine .on_exception , event_data )
718- else :
726+ # always re-raise BaseException!
727+ if not event_data .machine .on_exception or not isinstance (err , Exception ):
719728 raise
720729 except BaseException as err2 :
721730 _LOGGER .error ("%sHandling timeout exception '%s' caused another exception: %s. "
722731 "Cancel running transitions..." , event_data .machine .name , repr (err ), repr (err2 ))
723732 await event_data .machine .cancel_running_transitions (event_data .model )
733+ if not isinstance (err , Exception ):
734+ raise
724735 finally :
725736 AsyncMachine .current_context .reset (token )
726737 _LOGGER .info ("%sTimeout state %s processed." , event_data .machine .name , self .name )
0 commit comments