Emlyn Tech

August 10, 2009

Error handling in the StateMachine

Filed under: Uncategorized — Emlyn @ 11:10 pm

This follows from the previous post, and is a reply to Serendipity Seraph.

In a previous incarnation of this idea I did indeed have some error handling, but I was never able to quite get it to feel like it belonged. It seemed wrongly conceived. My practice in these situations is to remove the feature or leave it out of new versions, which is what I did here, and wait to see if it wants to come back in.

After doing some more thinking about this, I came to the conclusion that error handling is actually a large part of what state machines are all about in the first place. You should enumerate all the different things that can happen (ie: conditions that can occur), have states for handling all of these. So, there is an argument for no special error handling; unexpected occurrences mean your state machine is incomplete.

(btw in the past I also had a handler for transitions between states, allowing checking things, and diverting transitions elsewhere, but that too turned out to be redundant, and the whole thing feels better for its omission.)

An example with a database connection failing: Database connections don’t tend to tell you when they die, rather you are going about your business happily, executing queries, then blam, out of the blue, a failure. In this state machine environment, this kind of synchronous error is best handled by a try/catch and raising a condition in the OnNewState handler, eg:

 try
 {
   ... code for doing things on entering states
   ... including a line that hits the database
   connection.executesql(somesql); // or something like that, you get the drift
   ... more stuff, but we don't get this far
 }
 catch (DBException dbex)
 {
   DoSomethingWithException(dbex);
   _stateMachine.RaiseCondition(DBConnectionFailure);
 }

And of course you need to have transitions on DBConnectionFailure in your statemachine for every state where you don’t want to just ignore it. Note that what different parts of the machine need to do in case of DBConnectionFailure can be quite different.

A good contrast is where failures happen in an asynchronous manner. An example I recently worked on is where a modem drops out (loses Carrier Detect) (Yes, it’s appallingly old technology, but you get that at times). What happens in .net is that an event handler fires telling you that the pin state has changed for your serial connection. In the handler, you simply raise your condition (eg: _stateMachine.RaiseCondition(ConnectionLost)) and that’s all. The state machine will take it from there, assuming you’ve correctly set up your state machine to deal with ConnectionLost in all relevant cases.

I guess I could add some very simple support for error management, eg: a built in condition called UnexpectedErrorCondition, which the state machine would raise if the OnNewState handler ever throws an unhandled exception. You could have explicit transitions for this condition, but if you haven’t specified any, the machine would move to some specified error state (specified in the constructor just like Start and Stop are).

Another approach here would be setting up States hierarchically. In an hierarchical arrangement, when we look for transitions from state to state for a given transition, we would walk up the tree toward the root (ie: can’t find a transition for state x? Try x.parent, etc). This way “error handling” (ie: dealing with conditions which signal error conditions that can happen any time) can be dealt with at a high level grouping state, rather than having to be done explicitly at every state in the machine. I think that has promise, actually; currently, you do have to do a lot of cut and pasting to set up handling of error conditions explicitly in every state.

About these ads

3 Comments »

  1. Thanks for the article. Appreciated it.

    I’m looking at implementing a state-machine for a uni project and doing some research first. Still trying to wrap my head around whether exceptions are states in themselves (and the implications for the architecture).

    You suggested try, catch during an OnEnter.. but I’m not sure that adequately does what I need (OnExit for one, *might* throw an exception before the transition to the next state).

    Am very new to the state-driven approach, so sorry for ignorance there :-)
    Tim.

    Comment by Timothy Dobson — March 29, 2012 @ 1:18 am | Reply

  2. Hi Tim,

    I would emphasise this line from the post:

    “After doing some more thinking about this, I came to the conclusion that error handling is actually a large part of what state machines are all about in the first place. You should enumerate all the different things that can happen (ie: conditions that can occur), have states for handling all of these. So, there is an argument for no special error handling; unexpected occurrences mean your state machine is incomplete.”

    So yes, I’d go for modelling all error conditions as states. Not down to every possible error, mind you, group them up a bit :-)

    fwiw, I wouldn’t even have an OnExit event (can’t remember if I included this in my library). If you need to do something real (ie: that might fail) in OnExit, let’s call it X, consider making a new state called “DoingX”, transitioning to that, doing the work in the newstate/enter handler, proceeding to the next state immediately if it succeeds, or raising an error condition if it fails (which will take you to an error state where you can figure out what to do next).

    Comment by Emlyn — March 29, 2012 @ 8:42 am | Reply

    • Cheers! No ‘on-exit’ makes a great deal of sense. You’ve saved me from a (potentially) huge flaw in my initial architecture that would likely lead to overcomplication (possibly even abandonment if it got to that).

      University-level state theory really doesn’t prepare anyone for any real attempt, hey. Or maybe I should qualify that with ‘my university really doesnt..’. Could be what I’m aiming for (I guess a “client-server, state-driven model”), is perhaps too ambitious, but we’ll see. Good learning experience either way.

      Will have to see if I can nail down some ‘broad error states’ (more research on planned technologies). Thanks for starting me on a path with all this.

      Tim.

      Comment by Timothy Dobson — March 29, 2012 @ 1:53 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: