1
\$\begingroup\$

I have 2 different approaches I'm using to handle error state or Exceptions from within nested functions. Take the following code for example:

public void Func1()
{
    try
    {
        Func2(); 
        //... continued logic if no exception was encountered 
    }
    catch (Exception ex)
    {
        log(ex.Message);
        return;
    }

}

public void Func2()
{
    try
    {
        Func3();
    }
    catch (Exception ex)
    {
        log(ex.Message);
        throw;
    }
}

In the above sample, Func1 needs to know if Func2 (and other methods Func2 calls) have thrown an exception, so that it can continue with execution. This appears to me to be an obvious code-smell and it's something I'd like to avoid doing. Here's the next option I've tried:

public void Func1()
{
    try
    {
        bool success = Func2();
        if (!success)
        {
            //... continued logic if no exception was encountered
        }
    }
    catch (Exception ex)
    {
        log(ex.Message);
        return;
    }
}

public bool Func2()
{
    try
    {
        bool success = Func3();
        if (!success) return false;
        return true;
    }
    catch (Exception ex)
    {
        log(ex.Message);
        return false;
    }
}

Using this second method, the nested functions return a boolean to determine state and whether or not the calling function should continue. This also doesn't feel right to me. I'd really like suggestions on ways to handle situations like this where I'm calling nested functions (particularly when they return void because they do unrelated processing to the class). Thanks!

EDIT: updated from pseudo-code to valid C#.

\$\endgroup\$

closed as off-topic by t3chb0t, RobH, paparazzo, Vogel612, Heslacher Aug 17 '17 at 4:32

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Pseudocode is off-topic on Code Review. We'll be happy to take a look at your real code. \$\endgroup\$ – t3chb0t Aug 16 '17 at 18:12
  • 1
    \$\begingroup\$ There are very few variations from what I posted to the real code, but I'll make it valid C#. \$\endgroup\$ – John Aug 16 '17 at 18:14
  • \$\begingroup\$ I'm still not sure about it. Now it's no longer pseudocode but a hypothetical one which would still be off-topic. If you cannot provide a real example then I'm afraid your question is better asked at Software Engineering. Code Review tries to improve working code rather then answering philosophical questions ;-) \$\endgroup\$ – t3chb0t Aug 16 '17 at 18:23
  • \$\begingroup\$ I see. I'll keep that in mind for next time. Thanks! \$\endgroup\$ – John Aug 16 '17 at 18:25
  • \$\begingroup\$ Could you show us more code? I believe it can be split into smaller functions doing the work and returning data, then you could handle exceptions there or return null. \$\endgroup\$ – Michał Paszkowski Aug 16 '17 at 20:47
0
\$\begingroup\$

If shortly, using exceptions is not a code-smell.


In my opinion using bool return values is appropriate for methods that are purposed for checking some conditions. Examples:

bool CanFunc2BeCalled() {  ... }
bool TryParse(string s, out ... value) { ... }

Such methods specifically designed to return bool. It is the main job they do.

If a method should perform some actions and during its execution an exception can be occured I would not return bool to indicate a failure. An exception is the right choice for these cases.

Exceptions is a native conception of .NET so don't be afraid of them :) Also with good XML comment on methods you always know what exceptions the method can throw:

///<summary>
///...
///</summary>
///<exception cref="InvalidOperationException">Description of failure.</exception>
void Func2() { ... }

So if you are able to check that call of a method can cause an exception before its execution, create the method for checking some conditions and call it before:

private bool CanFunc2BeCalled() {  ... }

public void Func1()
{
    if (!CanFunc2BeCalled())
        return;

    Func2();    
}

But if you can't check if the Func2 can be safely called before its execution then dealing with exceptions is a good way and I would stick with it.

\$\endgroup\$
  • \$\begingroup\$ Good summary. I've played around with different styles and using baked in Exception handling still seems to be the cleanest and most straight-forward way to do this. \$\endgroup\$ – John Aug 17 '17 at 16:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.