Skip to content

Confusion about error.execution #644

Description

@Dolecor

The error.execution is causing me some confusion.

  1. Is it true that when defining the error_execution event in my machine, I must manually give it an id manually 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 the error.execution event. But it seems sm.allowed_events and sm.enabled_events() conflicts with the error_execution event.

    I will demonstrate this using the ErrorLogger example from the Error Handling section:

    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()}")
    

    I get the AttributeError exception:

    (.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'?
    

    I found that the problem disappears if I manually assign the name error.execution to the error_execution event:

    class ErrorLogger(StateChart):
        [...]
        error_execution = Event(running.to(failed, on="log_error"), id="error.execution")
    
  2. Is it true that error_execution event, by design, can be sent to the machine from "outside"?

    When I applied the workaround with Event(..., id="error.execution"), the sm.enabled_events() gives:

    Enabled events: [BoundEvent('process', delay=0, internal=False), BoundEvent('error.execution', delay=0, internal=False)]
    

    Note that error.execution is enabled event, and it can be sent to the machine from main().

    This snippet:

    sm = ErrorLogger()
    
    print(f"  Enabled events: {sm.enabled_events()}")
    
    if "error.execution" in sm.enabled_events():
        sm.send("error.execution", error=RuntimeError("Should this be possible?"))
    
    print(sm.last_error)
    

    gives:

      Enabled events: [BoundEvent('process', delay=0, internal=False), BoundEvent('error.execution', delay=0, internal=False)]
    Should this be possible?
    

    The error.execution event 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions