213

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

Community
  • 1
  • 1
Samuel Carrijo
  • 17,449
  • 12
  • 49
  • 59
  • 61
    I'd write a comment explaining why it should be empty. – Mehrdad Afshari Aug 05 '09 at 16:37
  • Some people also say that having a catch block at all is a bad idea. – Otávio Décio Aug 05 '09 at 16:38
  • 5
    ...or at least log that it was caught. – matt b Aug 05 '09 at 16:38
  • @John - I need to grab my copy again, but I believe I read something along these lines in the Framework Guidelines book (Cwalina and al) – Otávio Décio Aug 05 '09 at 16:41
  • joel spolsky doesn't like catch blocks (see http://www.joelonsoftware.com/items/2003/10/13.html) – lubos hasko Aug 05 '09 at 16:43
  • @John also mentioned here - http://msdn.microsoft.com/en-us/library/ms229005.aspx - "Do use try-finally and avoid using try-catch for cleanup code. In well-written exception code, try-finally is far more common than try-catch." – Otávio Décio Aug 05 '09 at 16:43
  • 2
    @ocdecio: avoid it for **cleanup** code, not avoid it in general. – John Saunders Aug 05 '09 at 16:46
  • @John - good point, although I got the impression overall that catch would not be a good idea - I actually use it and would like to see some more discusson on when/where to use. – Otávio Décio Aug 05 '09 at 16:48
  • 1
    @ocdecio: Another case to avoid using try..catch is when you catch exceptions for known types of failures. e.g. numeric conversion exceptions – MPritchard Aug 05 '09 at 16:49
  • 1
    @ocdecio - try..finally is better than try..empty catch because the error continues up the stack - to get either handled by the framework, or to kill the program and be displayed to the user - both outcomes are better than a "silent failure". – Nate Aug 05 '09 at 16:49
  • 1
    @lubos hasko - that was probably one of Joel's most controversial articles - http://fishbowl.pastiche.org/2003/10/14/taking_exception_to_joel_spolsky/ for many disagreements. – Nate Aug 05 '09 at 16:58
  • 1
    I agree that it may be correct to completely suppress the exception in your circumstance, but if you can catch the actual Exception subtype (e.g., IOException) that you expect to suppress, it will be more clear. Like you, I also name it 'ignored' instead of 'ex'. – Nelson Aug 05 '09 at 19:34
  • @Asmodon: As an aside, in some languages (like C#) it isn't necessary to name the exception at all (you can specify a type filter without a name). This prevents the compiler from warning you about declaring an unused variable, and also allows you to preserve the call stack by calling throw; again, which will throw the caught exception with the stack info intact. – Adam Robinson Aug 06 '09 at 18:31
  • and just asked again on programmers.se - http://programmers.stackexchange.com/questions/16807/is-it-ever-ok-to-have-an-empty-catch-statement – warren Nov 05 '10 at 13:44
  • @warren Is this website a duplicate of stackoverflow? I don't get why it is any different – Samuel Carrijo Nov 17 '10 at 18:40
  • @Samuel Carrijo - it's not an "exact duplicate" - if it were, it wouldn't exist :) .. from the p.se faq (http://programmers.stackexchange.com/faq) "Programmers - Stack Exchange is for expert programmers who are interested in subjective discussions on software development. " – warren Nov 17 '10 at 19:27
  • It depends, I had a situation where there was a chance of error while parsing/formatting date data from an external feed. Chances of invalid data was high. If you want to report/record it somewhere, you could do that in catch block. But I had to ignore such errors, so choose for empty try catch ;-) – vinodpthmn Oct 01 '14 at 10:00
  • When you are handling an exception, you might be not interested in any more Exceptions; for example if `java.io.FileInputStream.read` has thrown an Exception, you're supposed to call `java.io.FileInputStream.close`, but even if it also throws Exception, you just ignore it. – Lorinczy Zsigmond Jan 14 '19 at 10:39
  • It's like you have seen the problem and turn away your eyes from potential issue, moreover you might have exact clue why you are suppressing an exception, but think about future developer coming in and seeing and empty catch. She would have no idea why you placed empty block at first place. The worse is to catch generic exception and leave it empty i.e. *Instead of catching **IOExcpetion** you just caught **Exception** while handling file. – A.B. Apr 11 '20 at 14:17
  • What if I know what the error is, and I specifically don't care? For example, I have an array with items that may or may not be able to have a certain action performed on them. I can set up a try-catch, and if the catch triggers, I just move on to the next item in the array. There's nothing for the catch block to do. I know what the error is, and it doesn't require any response. – qwerty Jun 25 '20 at 15:35

20 Answers20

320

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
  • 364,293
  • 75
  • 561
  • 662
  • 4
    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 Aug 05 '09 at 16:50
  • 41
    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 Aug 05 '09 at 16:50
  • 3
    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 Aug 05 '09 at 17:08
  • 6
    @Jason: at the very least, you should include a detailed comment explaining why you are silencing the exceptions. – Ned Batchelder Aug 25 '10 at 19:14
  • @NedBatchelder I reckon "why I did something" comments are the only valid form of comments, otherwise code should be self documenting. – Aran Mulholland May 10 '12 at 02:01
  • 1
    This answer assumes two things: 1. That the exception being thrown is indeed a meaningful one and that the one who wrote the code that throws knew what he was doing; 2. That the exception is indeed an "error condition" and is not abused as control flow (although this is a more specific case of my first point). – Boris B. Sep 12 '13 at 08:34
  • 1
    @jason if you don't care whether it actually happens, and it might error, you should still log the error. I've seen someone patch out an empty catch for a piece of code that was hitting oracle millions of times a day with a query for a table that didn't exist in certain circumstances. This brought the DB to its knees twice in 2 weeks, and there was nothing on the application side to indicate that there was a problem because the developer's solution was a try with an empty catch. – umassthrower Sep 10 '14 at 20:43
  • 2
    you generalized that try-catch is bad idea! actually it is great idea. Imagine a system that does not have user interaction!? and should keep running!. In my case, my system should always continue working, 24/7. So It cant go off. In some cases, i try to write to file, and i dont care if it was not successfully done or not, what i care is to keep the whole system running – MBH Nov 21 '15 at 10:54
  • The only time I've done it is within an UnhandledExceptionHandler and I attempted to log the error to disk. As the exception was already unhanded I may not be able to save so I don't rethrow. This is so the user can still copy the message from the dialog before crashing. – rollsch Oct 17 '16 at 21:09
  • I used it as "if .at() threw, it doesn't exists, so leave the std::optional empty". Is that bad? – Post Self Jul 24 '17 at 09:42
  • I appreciate answer here @NedBatchelder, but I'm using an empty CATCH block, purely because the TRY block can hit databases I have no access to (which is acceptable), and as this code only ever gets run by a tester and is not embedded into any system procedures that will run on a daily basis, I feel it's OK to do this, but I do agree with the analogy.. – Northernlad Sep 20 '19 at 11:51
  • .NET always have default logging for crashing application. – Evgeny Gorbovoy Jun 26 '20 at 09:07
  • What if you have a global error handling like `axios interceptors`? Wouldn't a catch block be redundant? – Nima Jul 27 '22 at 04:47
37

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
  • 182,639
  • 35
  • 285
  • 343
12

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
  • 24,752
  • 10
  • 56
  • 61
  • 8
    You are certainly over-generalizing. Just because *you* do not need it does not mean that nobody does. Even if absolutely nothing can be done in response, there's somebody somewhere with a requirement to collect statistics on abandoned connections. So it's quite rude to assume "programmer of library doesn't know what he is doing". – Ben Voigt Sep 17 '13 at 22:34
11

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
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 4
    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 Aug 05 '09 at 17:07
  • 1
    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 Aug 05 '09 at 17:14
  • 2
    @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 Aug 07 '09 at 12:05
  • 2
    @Dave: While `catch (Exception) {}` is a bad idea, `catch (SpecificExceptionType) {}` might be perfectly fine. The programmer DID inspect the exception, using the type information in the catch clause. – Ben Voigt Sep 17 '13 at 22:37
10

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
  • 50,022
  • 18
  • 110
  • 131
9

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
  • 59,486
  • 16
  • 97
  • 135
9

Per Josh Bloch - Item 65: Don't ignore Exceptions of Effective Java:

  1. An empty catch block defeats the purpose of exceptions
  2. At the very least, the catch block should contain a comment explaining why it is appropriate to ignore the exception.
KrishPrabakar
  • 2,824
  • 2
  • 31
  • 44
7

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
  • 9,419
  • 7
  • 34
  • 41
3

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.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • 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 – MPritchard Aug 05 '09 at 16:44
  • Good point. I should probably note that in my response. – Powerlord Aug 05 '09 at 16:56
  • 1
    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 Aug 05 '09 at 17:13
  • 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 Lawrence Aug 05 '09 at 18:24
  • @Scott: Certain languages (i.e. Java) have checked exceptions... exceptions you're forced to write catch blocks for. – Powerlord Aug 05 '09 at 18:27
  • @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 Lawrence Aug 05 '09 at 20:30
  • @Scott: You're right, C# doesn't have checked exceptions. – Powerlord Aug 06 '09 at 14:29
3

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
  • 18,086
  • 12
  • 58
  • 77
2

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
  • 17,375
  • 3
  • 36
  • 39
2

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
  • 135
  • 1
  • 8
2

If you dont know what to do in catch block, you can just log this exception, but dont leave it blank.

        try
        {
            string a = "125";
            int b = int.Parse(a);
        }
        catch (Exception ex)
        {
            Log.LogError(ex);
        }
Andzej Maciusovic
  • 4,306
  • 1
  • 29
  • 40
1

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
  • 16,748
  • 5
  • 45
  • 59
1

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
  • 7,493
  • 6
  • 36
  • 49
  • 1
    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 ;) – MPritchard Aug 05 '09 at 16:42
  • 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 Aug 05 '09 at 18:51
  • 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 Aug 05 '09 at 18:58
  • 2
    -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 Aug 05 '09 at 22:47
  • Eek. The exception.Message could be localized and thus not what you expect. This is just wrong. – frankhommers Jun 03 '20 at 19:20
1

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)

AndersK
  • 35,813
  • 6
  • 60
  • 86
1

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
  • 114,645
  • 34
  • 221
  • 317
1
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
  • 45,363
  • 14
  • 64
  • 102
1

There are situations where you might use them, but they should be very infrequent. Situations where I might use one include:

  • exception logging; depending on context you might want an unhandled exception or message posted instead.

  • looping technical situations, like rendering or sound processing or a listbox callback, where the behaviour itself will demonstrate the problem, throwing an exception will just get in the way, and logging the exception will probably just result in 1000's of "failed to XXX" messages.

  • programs that cannot fail, although they should still at least be logging something.

for most winforms applications, I have found that it suffices to have a single try statement for every user input. I use the following methods: (AlertBox is just a quick MessageBox.Show wrapper)

  public static bool TryAction(Action pAction)
  {
     try { pAction(); return true; }
     catch (Exception exception)
     {
        LogException(exception);
        return false;
     }
  }

  public static bool TryActionQuietly(Action pAction)
  {
     try { pAction(); return true; }
     catch(Exception exception)
     {
        LogExceptionQuietly(exception);
        return false;
     }
  }

  public static void LogException(Exception pException)
  {
     try
     {
        AlertBox(pException, true);
        LogExceptionQuietly(pException);
     }
     catch { }
  }

  public static void LogExceptionQuietly(Exception pException)
  {
     try { Debug.WriteLine("Exception: {0}", pException.Message); } catch { }
  }

Then every event handler can do something like:

  private void mCloseToolStripMenuItem_Click(object pSender, EventArgs pEventArgs)
  {
     EditorDefines.TryAction(Dispose);
  }

or

  private void MainForm_Paint(object pSender, PaintEventArgs pEventArgs)
  {
     EditorDefines.TryActionQuietly(() => Render(pEventArgs));
  }

Theoretically, you could have TryActionSilently, which might be better for rendering calls so that an exception doesn't generate an endless amount of messages.

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
0

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
  • 965
  • 2
  • 12
  • 27