views:

2241

answers:

17

Hi, I've just seen a question on try-catch, which people (including Jon Skeet) say empty catch blocks are a really bad idea? Why this? Is there no situation where an empty catch is not a wrong design decision?

I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all

+4  A: 

Empty catch blocks are usually put in because the coder doesn't really know what they are doing. At my organization, an empty catch block must include a comment as to why doing nothing with the exception is a good idea.

On a related note, most people don't know that a try{} block can be followed with either a catch{} or a finally{}, only one is required.

Justin
+1 I'd stress the 'or' in that last sentence for added impact
MPritch
That second paragraph may be language-dependent, though, right?
David Zaslavsky
unless of course you're talking about IE6 or IE7 ;-) ... where the catch *IS* required or the finally doesn't execute. (this was fixed in IE8 btw)
scunliffe
source: http://webbugtrack.blogspot.com/2007/11/bug-184-catch-to-try-catch-finally-in.html
scunliffe
Very true. Might be worth highlighting the languages. I believe .net is fine
MPritch
No language was listed either in the question of the tags. In C++, you're wrong. There is no try {} finally {} in C++, largely because C++ has better ways to do cleanup.
David Thornley
+76  A: 

Usually empty try-catch is a bad idea because you are silently swallowing an error condition and then continuing execution. Occasionally this may be the right thing to do, but often it's a sign that a developer saw an exception, didn't know what to do about it, and so used an empty catch to silence the problem.

It's the programming equivalent of putting black tape over an engine warning light.

I believe that how you deal with exceptions depends on what layer of the software you are working in: Exceptions in the Rainforest.

Ned Batchelder
Love the analogy - spot on.
lc
In those truly rare circumstances where I *really* don't need the exception *and* logging is unavailable for some reason, I make sure to comment that it's intentional -- and why it's not needed, and reiterate that I'd still prefer to log it if it were feasible in that environment. Basically I make the comment MORE work than logging would have been had it been an option in that circumstance. Luckily I have but 2 clients for whom this is an issue, and it's only when sending non-critical e-mails from their web sites.
John Rudy
Also love the analogy - and like all rules, there are exceptions. For instance it's perfectly OK to use black tape over the blinking clock on your VCR if you never intend to do timed recordings (for all you old folk who remember what a VCR is).
Michael Burr
Like any departure from accepted practice, do it if appropriate and document it so the next guy knows what you did and why.
David Thornley
i disagree w/your analogy. i can see how it _may_ be like putting tape over a warning light, but not always. in the OP's question, if you try to execute something but don't care if it actually happens, there's no need to handle the error. of course i don't advocate not caring about what happens, but if it really is inconsequential, why write more code?
Jason
@Jason: at the very least, you should include a detailed comment explaining why you are silencing the exceptions.
Ned Batchelder
+12  A: 

They're a bad idea in general because it's a truly rare condition where a failure (exceptional condition, more generically) is properly met with NO response whatsoever. On top of that, empty catch blocks are a common tool used by people who use the exception engine for error checking that they should be doing preemptively.

To say that it's always bad is untrue...that's true of very little. There can be circumstances where either you don't care that there was an error or that the presence of the error somehow indicates that you can't do anything about it anyway (for example, when writing a previous error to a text log file and you get an IOException, meaning that you couldn't write out the new error anyway).

Adam Robinson
+2  A: 

An empty catch block is essentially saying "I don't want to know what errors are thrown, I'm just going to ignore them."

It's similar to VB6's On Error Resume Next, except that anything in the try block after the exception is thrown will be skipped.

Which doesn't help when something then breaks.

R. Bemrose
I'd actually say "On Error Resume Next" is worse - it'll just try the next line regardless. An empty catch will jump to pass the closing brace of the try statement
MPritch
Good point. I should probably note that in my response.
R. Bemrose
This is not exactly true, if you have an empty try...catch with a specific exception type, then it will ignore just this type of exception, and that might be legitimate...
Meta-Knight
But if you know a particular type of exception is being thrown, it seems like you might have enough information to write your logic in a way that avoids the use of try-catch to deal with the situation.
Scott A. Lawrence
@Scott: Certain languages (i.e. Java) have checked exceptions... exceptions you're forced to write catch blocks for.
R. Bemrose
@R. Bemrose, thanks for the info. I'm not a Java guy, so I wasn't aware of the checked exceptions feature. I don't think C# has them.
Scott A. Lawrence
@Scott: You're right, C# doesn't have checked exceptions.
R. Bemrose
+3  A: 

Exceptions should only be thrown if there is truly an exception - something happening beyond the norm. An empty catch block basically says "something bad is happening, but I just don't care". This is a bad idea.

If you don't want to handle the exception, let it propagate upwards until it reaches some code that can handle it. If nothing can handle the exception, it should take the application down.

Reed Copsey
Sometimes you know that it isn't going to affect anything. Then go ahead and do it, and comment it so the next guy doesn't just think you screwed up because you're incompetent.
David Thornley
Yeah, there is a time and a place for everything. In general, though, I think an empty catch block being good is the exception to the rule - it's a rare case where you want to truly ignore an exception (usually, IMO, it's the result of a poor use of exceptions).
Reed Copsey
@David Thornley: How do you know it isn't going to affect anything if you don't at least inspect the exception to determine whether it's an expected and meaningless error or one which should instead be propagated upward?
Dave Sherohman
+5  A: 

I think it's okay if you catch a particular exception type of which you know it's only going to be raised for one particular reason, and you expect that exception and really don't need to do anything about it.

But even in that case, a debug message might be in order.

balpha
+1  A: 

Because if an exception is thrown you won't ever see it - failing silently is the worst possible option - you'll get erroneous behavior and no idea to look where it's happening. At least put a log message there! Even if it's something that 'can never happen'!

Nate
+1  A: 

Empty catch blocks are an indication of a programmer not knowing what to do with an exception. They are suppressing the exception from possibly bubbling up and being handled correctly by another try block. Always try and do something with the exception you are catching.

Dan
A: 

It's probably never the right thing because you're silently passing every possible exception. If there's a specific exception you're expecting, then you should test for it, rethrow if it's not your exception.

try
{
    // Do some processing.
}
catch (FileNotFound fnf)
{
    HandleFileNotFound(fnf);
}
catch (Exception e)
{
    if (!IsGenericButExpected(e))
        throw;
}

public bool IsGenericButExpected(Exception exception)
{
    var expected = false;
    if (exception.Message == "some expected message")
    {
        // Handle gracefully ... ie. log or something.
        expected = true;
    }

    return expected;
}
xanadont
That's not really a standard pattern you're advising people to use there. Most people would just catch the Exceptions of whatever types they are expecting, and not the ones they're not. I can see some circumstances where your approach would be valid, just be careful of posting in a forum like this where people tend to be readng things like this because they don't understand in the first place ;)
MPritch
My intent was not that IsKnownException() is checking the type of the exception (yes, you should do that by different catch blocks), rather it's checking if it's an expected exception. I'll edit to make it more clear.
xanadont
I was originally thinking about COMExceptions. You can test for a specific ErrorCode and handle the codes you expect. I do this often when programming with ArcOjbects.
xanadont
-1 Making decisions in the code based on the exception message is a really bad idea. The exact message is rarely documented and could change at any time; it's an implementation detail. Or the message could be based on a localizable resource string. In any case it's only meant to be read by a human.
Wim Coenen
+7  A: 

I wouldn't stretch things as far as to say that who uses empty catch blocks is a bad programmer and doesn't know what he is doing...

I use empty catch blocks if necessary. Sometimes programmer of library I'm consuming doesn't know what he is doing and throws exceptions even in situations when nobody needs it.

For example, consider some http server library, I couldn't care less if server throws exception because client has disconnected and index.html couldn't be sent.

lubos hasko
+1  A: 

I find the most annoying with empty catch statements is when some other programmer did it. What I mean is when you need to debug code from somebody else any empty catch statements makes such an undertaking more difficult then it need to be. IMHO catch statements should always show some kind of error message - even if the error is not handled it should at least detect it (alt. on only in debug mode)

Anders K.
+5  A: 

There are rare instances where it can be justified. In Python you often see this kind of construction:

try:
    result = foo()
except ValueError:
    result = None

So it might be OK (depending on your application) to do:

result = bar()
if result == None:
    try:
        result = foo()
    except ValueError:
        pass # Python pass is equivalent to { } in curly-brace languages
 # Now result == None if bar() returned None *and* foo() failed

In a recent .NET project, I had to write code to enumerate plugin DLLs to find classes that implement a certain interface. The relevant bit of code (in VB.NET, sorry) is:

    For Each dllFile As String In dllFiles
        Try
            ' Try to load the DLL as a .NET Assembly
            Dim dll As Assembly = Assembly.LoadFile(dllFile)
            ' Loop through the classes in the DLL
            For Each cls As Type In dll.GetExportedTypes()
                ' Does this class implement the interface?
                If interfaceType.IsAssignableFrom(cls) Then

                    ' ... more code here ...

                End If
            Next
        Catch ex As Exception
            ' Unable to load the Assembly or enumerate types -- just ignore
        End Try
    Next

Although even in this case, I'd admit that logging the failure somewhere would probably be an improvement.

Daniel Pryden
I referred to log4net as one of those instances before I saw your answer.
Scott A. Lawrence
+1  A: 

I think a completely empty catch block is a bad idea because there is no way to infer that ignoring the exception was the intended behavior of the code. It is not necessarily bad to swallow an exception and return false or null or some other value in some cases. The .net framework has many "try" methods that behave this way. As a rule of thumb if you swallow an exception, add a comment and a log statement if the application supports logging.

complexcipher
+1  A: 

This goes hand-in-hand with, "Don't use exceptions to control program flow.", and, "Only use exceptions for exceptional circumstances." If these are done, then exceptions should only be occurring when there's a problem. And if there's a problem, you don't want to fail silently. In the rare anomalies where it's not necessary to handle the problem you should at least log the exception, just in case the anomaly becomes no longer an anomaly. The only thing worse than failing is failing silently.

Imagist
+1  A: 

Generally, you should only catch the exceptions you can actually handle. That means be as specific as possible when catching exceptions. Catching all exceptions is rarely a good idea and ignoring all exceptions is almost always a very bad idea.

I can only think of a few instances where an empty catch block has some meaningful purpose. If whatever specific exception, you are catching is "handled" by just reattempting the action there would be no need to do anything in the catch block. However, it would still be a good idea to log the fact that the exception occurred.

Another example: CLR 2.0 changed the way unhandled exceptions on the finalizer thread are treated. Prior to 2.0 the process was allowed to survive this scenario. In the current CLR the process is terminated in case of an unhandled exception on the finalizer thread.

Keep in mind that you should only implement a finalizer if you really need one and even then you should do a little as possible in the finalizer. But if whatever work your finalizer must do could throw an exception, you need to pick between the lesser of two evils. Do you want to shut down the application due to the unhandled exception? Or do you want to proceed in a more or less undefined state? At least in theory the latter may be the lesser of two evils in some cases. In those case the empty catch block would prevent the process from being terminated.

Brian Rasmussen
A: 
I mean, for instance, sometimes you want to get some additional info from somewhere (webservice, database) and you really don't care if you'll get this info or not. So you try to get it, and if anything happens, that's ok, I'll just add a "catch (Exception ignored) {}" and that's all

So, going with your example, it's a bad idea in that case because you're catching and ignoring all exceptions. If you were catching only EInfoFromIrrelevantSourceNotAvailable and ignoring it, that would be fine, but you're not. You're also ignoring ENetworkIsDown, which may or may not be important. You're ignoring ENetworkCardHasMelted and EFPUHasDecidedThatOnePlusOneIsSeventeen, which are almost certainly important.

An empty catch block is not an issue if it's set up to only catch (and ignore) exceptions of certain types which you know to be unimportant. The situations in which it's a good idea to suppress and silently ignore all exceptions, without stopping to examine them first to see whether they're expected/normal/irrelevant or not, are exceedingly rare.

Dave Sherohman
A: 

You should never have an empty catch block. It is like hiding a mistake you know about. At the very least you should write out an exception to a log file to review later if you are pressed for time.

Chadit