27

Possible Duplicate:
Are nested Try/Catch blocks a bad idea?

Currently I am using try catch within try catch ? The current senario requires it in our application.

void MyFun()
{
    try
    {
        //Process logic 1
        // ......
        try
        {
            //Process logic 2
            // ......
        } catch (Exception ex)
        {
            //write an error details in database
        }

        //Process Logic 3
        // ......

    } catch (Exception ex)
    {
        //show error msg
    }
}
Community
  • 1
  • 1
HotTester
  • 5,620
  • 15
  • 63
  • 97

7 Answers7

19

No particular problem with this especially if you want to handle the exceptions differently.
However, if the inner exception and the outer exception are of different types E1, E2 respectively and E1 is not a parent of E2, you can have two adjacent catch clauses.

try
{
  // do something
}
catch (E1 e1)
{
}
catch (E2 e2)
{
}

As noted by Rob and J.Steen - this is slightly different than the case in the question as in this case is E1 is thrown the code after it will not be executed.

Itay Karo
  • 17,924
  • 4
  • 40
  • 58
  • 1
    This isn't semantically the same, as he noted that there's processing logic after the inner catch block. – Rob Dec 07 '12 at 08:57
  • If `proccess logic 1` and `process logic 3` are only throwing `E2` while `process logic 2` is throwing `E1` it is the same. – Itay Karo Dec 07 '12 at 08:59
  • I suppose, but then why bother writing the code in the first place? – Rob Dec 07 '12 at 09:00
  • @Rob writing which code? – Itay Karo Dec 07 '12 at 09:01
  • 5
    No. If process logic 2 throws an exception, process logic 3 will never execute. It is not the same. – J. Steen Dec 07 '12 at 09:01
  • To be clear, @J.Steen is agreeing with me, correct? In the OP code, if PL2 throws, it's caught, and PL3 still executes. In your code, PL3 being inside the "try" will circumvent in the event that PL2 throws. – Rob Dec 07 '12 at 09:04
  • Yes, I'm agreeing with @Rob. This code will definitely execute differently than OP's. The answer may still be valid, of course. =) – J. Steen Dec 07 '12 at 09:05
3

A nested try/catch is fine. what you want to stay away from is changing the logical flow of your code based on the try catch. In other words, you shouldn't treat a try/catch as an if/else block. so this isn't ideal:

//over the top example just to demonstrate my point

public bool IsNumberTen(int x)
{
    try
    {
        if(x > 10)
            throw new NumberTooHighException();
        else if(x < 10)
            throw new NumberTooLowException();
        else
            return true;

    }
    catch(NumberTooHighException)
    {
        return false;
    }
    catch(NumberTooLowException)
    {
        return false;
    }
}
jb.
  • 9,921
  • 12
  • 54
  • 90
  • Is this really treating an exceptional case as an if/else? Replace func1() with File.Open(path) and func2() with MessageBox.Show("I couldn't open your file.") - it's not treating it like an if-else. – Rob Dec 07 '12 at 09:02
  • maybe i gave a bad example. i'll come up with a better, more explicit, one. – jb. Dec 07 '12 at 09:05
  • @Rob, see my updated example – jb. Dec 07 '12 at 09:11
1

This item suggests that its not a bad thing and that you would only have to handle the error in another way any way.

Exception handling try catch inside catch

Community
  • 1
  • 1
Chadwick13
  • 357
  • 1
  • 7
  • 15
1

I don't see why not. If you have logic in the catch which may fail or raise an exception that requires handling then it makes sense.

Faster Solutions
  • 7,005
  • 3
  • 29
  • 45
0

Its a little difficult to answer this question without knowing what logic is in here. Certainly in terms of performance, nested exception handling will incur a greater cost, but general rule of thumb is only catch exceptions that you as a developer understand how to handle. This overlaps into the practice of TDD where if you have a good enough set of tests you can identify where the expected exceptions should be, then this will dictate your exception logic.

0

I would say this: it's not bad. Whether it's good depends on your program, and whether such a concept makes sense given your method's logic and contracts.

Edit: I'd suggest checking out the article Exception Cost: When to throw and when not to. It outlines what is most expensive for exception management in the CLR.

Rob
  • 3,276
  • 2
  • 22
  • 25
  • 1
    For anyone stumbling across this years later, here's an archived link: https://web.archive.org/web/20150214200203/http://blogs.msdn.com/b/ricom/archive/2003/12/19/44697.aspx – kfoxon Apr 22 '21 at 16:04
0

I am trying to think of situations where you may want a nested block... perhaps if you are making database changes and you are using the try catch as a virtual transaction, you may want to try to update some properties but then carry on if that fails, but also catch an overall exception if and when you actually commit to the database update itself.

Even with this considered, you should never need to do this... It should be perfectly sufficient to simply stack blocks next to each other like so:

void MyFun()
{
    try
    {
        //Process logic 1
        // ......
    } catch (Exception ex)
    {
        //show error msg
    }
    try
    {
        //Process logic 2
        // ......
    } catch (Exception ex)
    {
        //write an error details in database
    }

}

It is also probably worth noting that if you find the need to nest try catch blocks then there is probably a better way you could be designing your code.

EDIT: Itay's answer is also somewhat better than nesting, although it will not allow you to carry on in the block once you have caught an exception.

Hope this helps!

beyond-code
  • 1,423
  • 1
  • 12
  • 20
  • Hint: "below" or "above" doesn't really apply when you're talking about other answers. I can sort this list of answers in various ways. But now I'm just nitpicking. =) – J. Steen Dec 07 '12 at 09:03