Can you give us us case for this? Why can't you handle every error type in the top level catch?
–
MoronsNov 9 '11 at 16:43

1

I've seen this kind of code recently, performed by unexperienced programmers who don't really know what they are calling inside the try blocks, and they don't want to bother testing the code. In the code sample I've seen, It was the same operation but performed each time with fallback parameters.
–
Mister SmithNov 9 '11 at 16:50

@LokiAstari -Your example is a try in the Finally Section.. Where there is no Catch. This is a nested in the Try section.. It's different.
–
MoronsNov 9 '11 at 17:50

Yes this is sort of what I was trying to get at. Of course there comes a point in your nested try/catch statements where you just have to say enough is enough. I was making a case for nesting as opposed to sequential try/catch's, saying that there are situations where you only want the code inside the second try to execute if the first try falls over.
–
AndrewCNov 9 '11 at 16:40

Then just use the TrySeveralThingsStrategy, which is a kind of composite strategy (two patterns for the price of one!).

One huge caveat: don't do this unless your strategies are themselves sufficiently complex, or you want to be able to use them in flexible ways. Otherwise, you're larding a few line of simple code with a huge pile of unnecessary object-orientation.

I don't think it's automatically an anti-pattern, but I'd avoid it if I can find an easier and cleaner way to do the same thing. If the programming language you're working in has a finally construct, that might help clean this up, in some cases.

Basically it's a heuristic. One failed attempt to connect could just be a network glitch, but if it happens twice, that probably means the machine you're trying to connect to really is unreachable. There are probably other ways to implement this concept, but they'd most likely be even uglier than the nested tries.

Code like the one you showed does indeed not make any sense in most if not all cases. However, the OP was referring to nested try-catches, which is a quite different question than that for multiple consecutive statements.
–
Hanno BinderNov 9 '11 at 18:59

I've "had" to do this in a test class coincidentially (JUnit), where the setUp() method had to create objects with invalid constructor parameters in a constructor that threw an exception.

If I had to make the construction of 3 invalid object fail, for example, I would need 3 try-catch blocks, nested. I created a new method instead, where the exceptions where caught, and the return value was a new instance of the class I was testing when it succeeded.

Of course, I only needed 1 method because I did the same 3 times. It might be not such a good solution for nested blocks that do totally different things, but at least your code would become more readable in most cases.

In some cases a nested Try-Catch is unavoidable. For instance when the error recovery code itself can throw and exception. But in order to improve the readability of the code you can always extract the nested block into a method of its own. Check out this blog post for more examples on nested Try-Catch-Finally blocks.

Not an anti-pattern per se, but a code pattern that tells you need to refactor.

And it's pretty easy, you just have to know a rule of thumb which is writing no more than a try block in the same method. If you know well to write related code together, usually is just copying and pasting each try block with its catch blocks and pasting it inside a new method, and then replace the original block with a call to this method.

This rule of thumb is based on Robert C. Martin's suggestion from his book 'Clean Code':

if the keyword 'try' exists in a function, it should be the very first
word in the function and that there should be nothing after the
catch/finally blocks.

A quick example on "pseudo-java". Suppose we have something like this:

Then we could refactor each try catch and in this case each try-catch block tries the same thing but in different locations (how convenient :D), we have only to copy paste one of the try-catch blocks and make a method of it.