Search code examples
c++error-checking

Techniques for testing and report multiple function call return errors


I'm looking at error testing and reporting techniques from function calls, especially when multiple functions are called. As an example of what I mean, for simplicity each function returns a bool:

success = false;

if (fnOne ())
{
    if (fnTwo ())
    {
        if (fnThree ( ))
        {
            success = true;
        }
        else
        {
            cout << "fnThree failed" <<endl;
        }
    }
    else
    {
        cout << "fnTwo failed" <<endl;
    }
}
else
{
    cout << "fnOne failed" <<endl;
}

I find with the above example (which I see everywhere) the code quickly becomes unreadable, especially when it calling code becomes multi-screen in height.

Currently my way of dealing with this in C++ (Including 'c' tag in case someone has a C technique which is smooth) I store a bool and a string in my object. The bool represents success/fail and the string represents a reason for the fail state. I call a function and if the function fails, the function internally sets the object into fail state and provides a string based reason. I'm still not 100% happy with this method... but its the best I have so far. Example of what it looks like:

void myobj::fnOne (void)
{
    if (m_fluxCapacitorProngCount > 3)
    {
        setState (false, "myobj::fnOne - Flux capacitor has been breeding again");
    }
}

void myobj::fnTwo (void)
{
    if (m_answerToLifeUniverseAndEverything != 42)
    {
        setState (false, "myobj::fnTwo - Probability drive enabled?");    
    }
}

void myobj::setup (void)
{
    // Ensure time travel is possible
    if (valid())
    {
        fnOne ();
    }

    // Ensure the universe has not changed
    if (valid())
    {
        fnTwo ();
    }

    // Error? show the reason
    if (valid() == false)
    {
        cout << getStateReason () << end;
    }
}

Where valid () returns true/false and getStateReason () returns the string provided in the function when the error occured.

I like that this grows without the need to nest the conditions, to me I find this more readable but I'm sure there are problems...

What is the best [cleanest] way to handle detecting and reporting multiple function call return conditions?


Solution

  • This code should be clearer than your first variant:

    if (!fnOne ())
    {
        cout << "fnOne failed" <<endl;
        return;
    }
    if (!fnTwo ())
    {
        cout << "fnTwo failed" <<endl;
        return;
    }
    if (!fnThree ())
    {
        cout << "fnThree failed" <<endl;
        return;
    }
    success = true;
    

    In general, for C++ you can use exceptions for error handling.