Pergunta

I call a lot of outside functions from within my state machine - either explicitly like sendMessage(...) or implicitly like a!=b. So far I have tried to keep track of what can throw, but as the number grows so does the need for a better method. Missing an exception and allowing it to propagate into the state machine framework's code would obviously cause a lot of mayhem.

I see three options but I hope someone can point me to a better one:

  1. Put a try catch at each onEntry, onExit and action. Since there are many of them and they are pretty shot, this would almost double the length of code and decrease readability.

  2. Make a whole lot of functions noexcept. This seems impossible in cases where the function is used somewhere else, or where it can legitimately throw and the exception is the only good solution.

  3. Modify most of the functions I call to use alexandrescu's Expected<T> as a return type. See: http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C

Which option is best? Is there an even better strategy?

Foi útil?

Solução

Instead of wrapping each and every onEntry, onExit and action in try catch block, better approach would be to implement noexcept wrapper versions of onEntry, onExit and action that would simply call onEntry, onExit and action within try catch block and handle any exceptions thrown.

In code you simply call only wrappers instead of actual functions, using exception handling to your advantage but avoiding duplicating try/catch logic.

void onExitWrapper(int arg1, int arg2) noexcept
{
try
{
onExit(arg1,arg2);
}
catch(/*whatever*/)
{
//handle exception
}
}

If exception handling is similar for different functions, you can also create special function that receives function pointer/lambda and input arguments, and calls function referenced by function pointer with input arguments inside try catch:

template <class Arg1,class Arg2,class Ret> Ret exceptionHandler(Ret (funcPtr *)(Arg1,Arg2),Arg1 arg1,Arg2 arg2)
{
    Ret output;
    try
    {
     output = funcPtr(arg1,arg2);
    }
    catch(/*whatever*/)
    {
    //handle exceptions
    }
    return output;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top