Menu

Exceptions

Developers
2009-08-12
2013-05-28
  • Gregor Krajcovic

    I'm using SMC to generate C# code.
    If an exception is thrown in the <i>Exit</i> action of the state, the state machine remains in that state.
    In my opinion the state machine shall be in some <i>"unknown state"</i> in which it would react only to transitions defined in <i>Default</i> pseudostate.
    If the state machine remains in the same state, its <i>Exit</i> action will be done again with the next transition, what is incorrect from two reasons:
    1. the programmer counts with the fact Exit actions are done only once
    2. it can end in a dead lock if the actions would throw the exception again

    I don't know whether it is correct to leave the state machine in an unknown state, whether it doesn't break the filosophy or design. Please discuss it.

    We shall also discuss the Entry action because the same applies to it - if there is an exception, can we conclude the state machine is in the state or not ?

     
    • Charles Rapp

      Charles Rapp - 2009-08-29

      What is the difference between SMC having the FSM remain in the original state or going to an "unknown" state when the developer expects to transition to yet a different state? I could see my way to allowing a well-known, reserved "Error" state. If an Exit, guard, transition or Entry action throws an exception, SMC sets the current state to the Error state if the Error state is defined. If not defined, then SMC behaves as it currently does for backward compatibility.

       
    • Gregor Krajcovic

      > What is the difference between SMC having the FSM remain in the original state or going to an "unknown" state when the developer expects to transition to yet a different state?

      If there was an exception the object is neither in the original state nor in the expected after-transition state.

      The "Error" state seems to be ok, but it I'm not fully satisfied with it. I just see that exceptions as a programming mechanism are not treated well in SMC. I would like to have the same flexibility as is in the programming language in SMC. Sometimes I know how to handle the specific exception in a specific situation and I would like to do it. If all exceptions would end up in the "Error" state I would loss all the possibility to handle them properly according to their origin or type.
      In projects I'm implementing using SMC I catch all exceptions and I change them to the transition "Exception". This is easily done in C#. The advantage of this solution are:
      1. I didn't touch the SMC it self
      2. I can react to a specific exception using guards
      3. I can react specifically in each state or have a general handler in "Default"
      Disadvantage:
      1. It is not clear where the exception occured ( whether in entry/exit/transition/guard )
      2. An exception in Exit causes deadlock
      3. Uncertain way of the created exception message ( will it be processed in the following state or in Default if the exception was thrown from a transition ... )

      My solution helped me a lot, I used it many different state machines, but it is not perfect because it's a hack. I see strong necessity to create a general solution for SMC.
      As the starting point we shall define goals we shall achieve. Here is my proposal:
      1. Exception handling shall be a natural attribute of SMC, not a hack.
      2. It shall be defined well what happens in case of an exception in all possible situations.
      3. SMC shall in any way notify about the exception origin, so it can be handled by the programmer properly

       
  • Charles Rapp

    Charles Rapp - 2009-09-20

    (This entry was copied from Gregor's e-mail due to problems with this forum.)

    Hallo !

    I cannot access the developers forum, so I send you my message here.
    ______________________________________________________
    PLEASE READ TILL THE END.
    In the past days I studied what others have to say to exception handling in state machine concept. I concluded following:

    1. Exceptions shall be represented as special events in the state machine.
    2. Any kind of action - entry, exit or transition - shall be considered as an atomic unit. There is no need to have fine grained exception handling inside the action.
    3. A guard is not an action, thus it is not clear how to handle it, I think it is ok to catch exception for it as whole ( the same as actions ).

    I propose following syntax:
    There will be new special exception block. It will be very similar to transitions definition, because an exception
    shall be treated as an event. There will be only one difference - no transition names, only arguments. I propose it to simplify
    it for the programmer. Guards are allowed.
    Language elements which can be followed by the exception block:

    1. exit block
    2. entry block
    3. transition block
    4. guard
    5. transitions block
    6. state name. Any exception thrown in any code called from any element of the state which is not handled locally will be dispatched here.

    ___________________________________
    Example of the exception block:
    &lt;pre&gt;
    &lt;code&gt;
    :Exception
    {
      ( val: Type1 ) new_state1
      {
          action
      }
      ( val: Type2 )   new_state2
      {
      }
      ( val: Type2 )  new_state2
      {
          action1();
      }
      ( val1: Type2, val2: Type3 ) push( new_state3 )
      {
          action2();
      }
      default pop
      {
      }
      … etc
    }
    &lt;/code&gt;
    &lt;/pre&gt;
    Example of the state definition containing exception blocks:
    &lt;pre&gt;
    &lt;code&gt;
    StateA
    :Exception
      {
          // handling of exception thrown from any method called in Entry, Exit, any transition or guard declared in this state.
          Default GeneralError
          {
          }
      }
    Entry
    {
      ReadData();
      StoreData();
    }:Exception
      {
          // handling of exception thrown from any method called in Entry
          ( e: IoException )  EofError
          {
              // guards are allowed here too
          }
          ( e: IoException ) IoError
          {
          }
          Default GeneralError
          {
          }
      }
    {
      Event1    StateB
      {
          WriteData();
      }:Exception
          {
              // handling of exception thrown from any method called in the transition
              ( e: IoException )    DataWriteError
              {
              }              }
      Event2( count: int ) StateC
      :Exception                                   {
                                      // handling of exception thrown during guard execution
                                      Default GuardError
                                      {
                                      }
                                  }
      {
      }
    }:Exception
      {
          // handling of exception thrown from any transition or guard
          ( e: TimeoutException ) TimeoutError
          {
              ResetTimer();
          }
      }
    &lt;/code&gt;
    &lt;/pre&gt;
    ________________

    It would be excelent if the exception block could be handled by SMC the same as an ordinary state definition, that means, it could contain entry, exit actions
    and nested exception blocks. If we would go this way and we will start to modify the compiler maybe we will discover it is not
    so difficult to implement.

    Advantages of my proposal:

    1. Syntax is fully backward compatible, existing sm code will not be broken.
    2. Syntax of exception blocks doesn't contain any new elements to learn, thus it can be adopted by the programmer instantly. For us it will be not so difficult to modify SMC because we can reuse existing code.
    3. It is very clear which part of the code is covered by the exception handling.

     
  • Charles Rapp

    Charles Rapp - 2009-10-01

    First a review of where SMC stands today:

    1.SMC is a a macro generator not a programming language. It is deliberately simply in concept and syntax.

    2.  SMC is now 9 years old, used world-wide and a lot of dependent FSMs.

    3. Exception handling is a programming language construct, not an FSM construct.

    Adding exception handling to the SMC syntax may appear elegant but is inherently buggy due to exceptions being foreign to FSMs. What exactly is an exception? That depends on the programming language you are using. Exceptions are implemented differently by different languages. SMC-generated code has as little to do with exceptions as possible and does not prevent exceptions reaching the application code. Therefore, an application can handle exceptions thrown during a transition by placing the transition method call inside a try-catch block. The catch block can then issue an exception transition which can perform the appropriate error recovery.

    My programming experience has taught me that when you merge inconsistent ideas (exceptions and FSMs) you end up with inherently buggy software. Exception handling is an idea I understand. Finite state machines is an idea I understand. But I don't understand exception handling in FSMs.

     
  • Gregor Krajcovic

    I fully agree with the fact that exceptions are not a part of FSM. But they are part of the underlying language. So we cannot ignore them.
    If SMC would be a compiler in its own language in which exceptions do not exist, than of course there is no need to mention them. But SMC is working with languages which have exceptions, thus it's worthy considering what to do with them.
    You propose a programmer shall place try/catch into called method. There are following problems:

    1. It is not possible, if he has no access to the source code of the context class. It is possible to write a wrapper, but that's not an elegant solution - a plenty of copy/paste/modify code. Who likes that ?
    2. Actions may contain assignment. How to try/catch that ?
    3. Actions in SMC code may contain calls to many methods and assignments. It is not possible to encapsulate them as whole in try/catch - *and actually my proposal was to achieve this, because it is fairly simple to be implemented in SMC.*
    4. In my opinion the context class shall not know that it is a part of FSM. It means it shall provide methods but it shall not know anything about states or transitions.I programmed really complex and high safety requiring applications with SMC and this concept prove to be very good. Programming of FSM is completely split from native language programming, leading to very well defined responsibilities (responsibility of FSM and the context class). Changes in SMC and native code doesn't affect each other, because there is no hidden dependency.     Thus if we omit exceptions in FSM and will ask only native language to deal with them or they will never be promoted to FSM or if they will be there will be strong dependency between FSM and context class (for example the same exception in the same method must be treated differently in different states. That means the context class must know about state machine states, that means if the state name changes or a new state is added, context class has to be modified too).

    I agree with you that SMC is very light weight and easy to use and that's why it works well and seems to be popular. I know that bloating is very dangerous for the project. I spent long time thinking before I wrote my proposal. I tried to design something what doesn't break existing SMC language syntax, what has short learning time for the programmer, what doesn't break existing FMSs and makes use of already existing code in SMC.

    I would like to know your motivation not to work with exceptions in SMC. I know mine - I programmed real projects and exceptions just cannot be ignored. To achieve real software productivity I needed to handle them in SMC code, because all &quot;tricks&quot; (handling in native language) turned out to be too expensive.
    Do you really want to ignore exceptions in FSMs as a concept or are you afraid of complexity of SMC changes ?

    Please take a look at following:

      : http://books.google.com/books?id=G384GCaECg8C&amp;lpg=PT177&amp;ots=7z0xFu4HM0&amp;dq=%22state%20machine%22%20%22exception%20handling%22&amp;pg=PT332#v=onepage&amp;q=%22state%20machine%22%20%22exception%20handling%22&amp;f=false

     
  • Charles Rapp

    Charles Rapp - 2009-10-17

    Would the &quot;-rawaction&quot; command line option I mentioned in the &quot;Accessing static methods&quot; feature request (2718920) resolve this issue. If &quot;-rawaction&quot; is specified then transition, entry and exit actions are read in verbatim and echoed to the target source file. The programmer using this option can use the target language in complete freedom including exception handling features.

    The only downside to this idea is that context class method calls must use &quot;ctxt.&quot; but that is no different than in transition guard statements.

    As for transition guards, the SMC generated code should wrap that code within a separate guard subroutine which returns a boolean. This subroutine then wraps the guard condition inside an exception handling block to protect against thrown exceptions. If the guard code throws an exception then false is returned. The generated guard code calls this SMC-generated method instead of the the user code directly.

    So does &quot;-rawaction&quot; meet your needs? What I like about the idea is that it keeps SMC language-feature neutral and opens up to SMC programmers greater flexibility.

     
  • Charles Rapp

    Charles Rapp - 2009-10-17

    One more thought about &quot;-rawaction&quot;. How about adding a method FSMContext.redirect(State state) wherein the programmer could dynamically change the next state from within the transition actions? So if the transition's raw code catches an exception, the next state could be changed on the fly.

     
  • Gregor Krajcovic

    Please see my remarks about &quot;-rawaction&quot; option in &quot;Accessing static methods&quot; forum.&lt;p&gt;I think approach you propose can solve exceptions handling. But I don't understand what you wrote for guards. How will the exception be passed to the sm code to be handled ? &lt;p&gt;The problem of guards is they must return boolean value. If we will allow any raw code inside of them, how to pass this value to FSM object ? I have two ideas:

    1. If we will support local raw code marks instead of the global option, than for guards it will be required to have exactly one statement non raw and value returned by it will be tested in FSM. This solution has following advantages - it doesn't break existing sm code; the programmer will have full raw code flexibility in guards; exception handling will be exactly the same as in other sm parts and correctness of the guard statement can be tested in compilation time. Disadvantage: eventhough the code will be not marked as raw, its syntax has to be raw ( because guards are raw code now ).
    2. To use a specific FSM method to get the boolean result. It will be required to call the method exactly once in the guard code. Advantage: global raw code option support; easy to implement in SMC. Disadvantage: it will not be detected in compilation time, that the method was not called and it breaks existing sm code.

     

Log in to post a comment.