Before sending an event to the state machine, I check whether the event can be triggered using sm.allowed_events. Then I needed to catch all unhandled exceptions that could be raised by the listeners (StateChart itself, Model, etc.). I learned from the Error Handling page that this can be done by adding handlers for the error.execution event. But it seems sm.allowed_events and sm.enabled_events() conflicts with the error_execution event.
from statemachine import State, StateChart
class ErrorLogger(StateChart):
running = State(initial=True)
failed = State(final=True)
process = running.to(running, on="do_process")
error_execution = running.to(failed, on="log_error")
def do_process(self):
raise ValueError("bad data")
def log_error(self, error):
self.last_error = error
When I try to get enabled events after the machine reaches a stable configuration:
sm = ErrorLogger()
print(f" Enabled events: {sm.enabled_events()}")
(.venv) PS <...>> sm-test.exe
Traceback (most recent call last):
File "<frozen runpy>", line 203, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "<...>\.venv\Scripts\sm-test.exe\__main__.py", line 5, in <module>
sys.exit(main())
~~~~^^
File "<...>\src\sm_test\__main__.py", line 57, in main
print(f" Enabled events: {sm.enabled_events()}")
~~~~~~~~~~~~~~~~~^^
File "<...>\.venv\Lib\site-packages\statemachine\statemachine.py", line 450, in enabled_events
result = self._engine.enabled_events(*args, **kwargs)
File "<...>\.venv\Lib\site-packages\statemachine\engines\sync.py", line 191, in enabled_events
"event": getattr(sm, event),
~~~~~~~^^^^^^^^^^^
AttributeError: 'ErrorLogger' object has no attribute 'error.execution'. Did you mean: 'error_execution'?
class ErrorLogger(StateChart):
[...]
error_execution = Event(running.to(failed, on="log_error"), id="error.execution")
The
error.executionis causing me some confusion.Is it true that when defining the
error_executionevent in my machine, I must manually give it anidmanually usingEvent(..., id="error.execution")?Before sending an event to the state machine, I check whether the event can be triggered using
sm.allowed_events. Then I needed to catch all unhandled exceptions that could be raised by the listeners (StateChart itself, Model, etc.). I learned from the Error Handling page that this can be done by adding handlers for theerror.executionevent. But it seemssm.allowed_eventsandsm.enabled_events()conflicts with theerror_executionevent.I will demonstrate this using the
ErrorLoggerexample from the Error Handling section:When I try to get enabled events after the machine reaches a stable configuration:
I get the
AttributeErrorexception:I found that the problem disappears if I manually assign the name
error.executionto theerror_executionevent:Is it true that
error_executionevent, by design, can be sent to the machine from "outside"?When I applied the workaround with
Event(..., id="error.execution"), thesm.enabled_events()gives:Note that
error.executionis enabled event, and it can be sent to the machine frommain().This snippet:
gives:
The
error.executionevent is described as an internal mechanism of the machine, and it’s strange that this event can be sent from "outside".python-statemachine versions 3.0.0, 3.1.0, 3.2.0, and 3.2.1 work identically with the specified code snippets.