
E. Gladyshev wrote:
----- Original Message ----- From: "Andreas Huber" <ah2003@gmx.net> [...] It's been a long discussion. It'd be helpful if you could summarize the proposed changes on d'tor/exit() and exception handling in general.
Ok, I will.
I have reached sort of a conclusion:
1. boost::fsm users want to have the option to just let exceptions "fly" through the framework and let the state machine client handle the problem. Whenever this happens the state machine object is no longer usable. Before handing the exception to the user, the framework should probably destruct (but not exit) all state objects.
If "fly through" is what I think it is (exceptions are not caught by the framework), it is one or another. You cannot "let exceptions "fly" through the framework" and destroy all states at the same time.
What I meant was the default behavior we were talking about before. I rephrase, trying to stick more to accepted exception handling terminology: 1. By default, boost::fsm is completely neutral to exceptions. All exceptions thrown by user actions are propagated to the state machine client. If such an exception is caught by client code, all state objects are destructed (but not exited). This ensures that the state machine object is in a defined state if client code uses it after handling the exception. State objects are constructed on state entry. On state exit, the states exit() function is called (if present) and the state object is destructed afterwards. Exceptions can be propagated from all user code except state destructors.
2. boost::fsm users might want to gracefully handle exceptions propagated from actions and continue to use the state machine object afterwards. If so, they must accept that exit actions must not propagate any exceptions. This is because it seems that, no matter how action failures are handled in a state machine, in general exit actions must be executed before an error-handling state can be reached.
I believe that it is similar to how things work now (with the default ExceptionTranslator)?
Yes.
I think the only way to avoid the non-throwing exit actions in 2 is to use the ephemeral error state or the exit() error handling you proposed for *all* failures, not only for exit. It is worth to explore this some more.
"ephemeral error state" makes me nervous. :)
Me too. I haven't got very far yet on the precise semantics. Whenever I try to formulate how exit() failures are handled I find myself trapped in inconsistencies. Contrary to Darryls proposal my gut feeling is that we have not left a state when its exit action fails. As a result, the exit() action of a particular state object could be called more than once, which I find *very* strange. Maybe Darryls way to handle things is better nevertheless ... Regards, Andreas