qmuntal / stateless

Go library for creating finite state machines
BSD 2-Clause "Simplified" License
942 stars 49 forks source link

Error control flow poorly documented #23

Closed soypat closed 3 years ago

soypat commented 3 years ago

After Ctrl+F'ing the go reference page for error handling documentation I can't be sure what happens if an Entry handler returns an error... does the program panic? Does it prevent the state transition and return to previous state (behaviour I would infer)? Some documentation on OnEntryFrom and OnEntry, among others would be nice. Below is an example of what I mean by returning error

SM.Configure(state.TestSystems).OnEntryFrom(trigger.TestSystems, 
        func(c context.Context, i ...interface{}) error {
        act := drivers.FromContext(c)
        if act == nil || act[0] == nil {
            return errors.New("got nil actuator slice in state machine") // what happen?
        }
        setZero(act)
        return nil
    })
qmuntal commented 3 years ago

TL;DR Agree that the error handling documentation can be improved. I'll work on it for the next release.

Any error created inside trigger actions will be returned in the Fire call that triggered the failing action. panics are only thrown when there is a misconfiguration of the state machine.

There is no rollback mechanism for handling errors after the state has changed. If you want to handle this situations gracefully you can either:

sm.Configure(stateA).
  Permit(trigger1, stateB, func(c context.Context, i ...interface{}) bool {
    act := drivers.FromContext(c)
    return act != nil && act[0] != nil
  }).
  OnEntry(func(c context.Context, i ...interface{}) error {
    act := drivers.FromContext(c)
    setZero(act)
    return nil
})
sm.Configure(stateA).
  OnEntry(func(c context.Context, i ...interface{}) error {
    act := drivers.FromContext(c)
    if act == nil || act[0] == nil {
      sm.Fire(triggerUnexpectedSituation)
      return nil
    }
    setZero(act)
    return nil
})
soypat commented 3 years ago

Maybe I was a bit blunt with the issue. Just like to clarify I absolutely love this library. Thank you for the work you put into it!