67

I thought about it and could not come up with an example. Why would somebody want to catch an exception and do nothing about it? Can you give an example? Maybe it is just something that should never be done.

15 Answers 15

83

I do it all the time with things like conversion errors in D:

import std.conv, std.stdio, std.exception;

void main(string[] args) {  
    enforce(args.length > 1, "Usage:  foo.exe filename");

    double[] nums;

    // Process a text file with one number per line into an array of doubles,
    // ignoring any malformed lines.
    foreach(line; File(args[1]).byLine()) {
        try {
            nums ~= to!double(line);
        } catch(ConvError) {
            // Ignore malformed lines.
        }
    }

    // Do stuff with nums.
}

That said, I think that all catch blocks should have something in them, even if that something is just a comment explaining why you are ignoring the exception.

Edit: I also want to emphasize that, if you're going to do something like this, you should be careful to only catch the specific exception you want to ignore. Doing a plain old catch {} is almost always a bad thing.

  • Some IDEs allow you to specify that a particular name for the exception (usually "ignore") indicates that you are purposely ignoring it, which suppresses the warning it would otherwise show; this takes the place of the comment. – Alex Feinman Nov 4 '10 at 14:46
  • I'm not familiar D, but I assume it is possible to do something like bool TryParse(string line, out double valToParse), which may be cleaner. – ysolik Nov 4 '10 at 15:54
  • @ysolik: No, this isn't included in the std. lib. – dsimcha Nov 4 '10 at 16:06
  • @ysolik: I'd imagine that would wrap the parse function with a try and empty catch anyway... – JohnL Nov 4 '10 at 16:15
  • 4
    Like @Michael says -- it's not quite empty since you've got the comment there; it should be obligatory to add a "this catch intentionally left blank" comment if there isn't a statement – STW Nov 4 '10 at 20:54
52

One example where I think is OK to just swallow exception without doing anything, even logging the exception, is inside logging code itself.

If you tried to log something and got exception there is not much you can do about it:

  • you can not log it of course;
  • you might be able to fall back to a reserve logging mechanism, but most applications are not that sophisticated, and for those that are sophisticated enough the same design problem will arise with the reserve logging mechanism;
  • fast fail - will be too radical a solution for most applications;
  • throwing exception up will do little good as it will end up in a catch statement up the stack that will almost certain try to log it...

That leaves you with the "least of the evil" option of quietly swallowing it, allowing the application to keep performing its main job, but compromising the ability to troubleshoot it.

  • 10
    great point. debugging the debugging code is always a challenge. – DevSolo Nov 4 '10 at 14:57
  • 7
    This, a million times. Especially when you consider that if you're logging, you may be in a terrible state; you could be out of memory, could be crashing, could be anything. At this point, when you're logging an error, and THAT fails, the only responsible thing to do is nothing; you have no guarantee that anything you try will not make it worse. – GWLlosa Nov 4 '10 at 19:55
  • Great point. In my logging code, I also like to add the InnerMessage for the exception. Many times this is null, so trying to add it would blow up the logging itself. – Tangurena Nov 5 '10 at 2:38
  • @Tangurena If it's often null then handle that, don't blow. In C# I often guard such things by ?? ""; – Loren Pechtel Jan 1 '18 at 1:43
8

If an exception is thrown by an operation that was optional anyway, there might be nothing to do. It might not be useful to log it. In that case, you may just want to catch it and do nothing.

If you're doing this, include a comment. Always comment anything that looks like a bug (fallthrough in a switch statement, empty catch block, assignment in a condition).

You might argue that this isn't a proper use of exceptions, but that's for another question.

| improve this answer | |
6

As a general rule, no. You either want to throw the exception up the stack, or log what happened.

However, I often do this when I'm parsing strings and converting to numbers (especially in mapping projects that are of the use-once and throw away variety).

boolean isNonZeroNumber = false;

try {
   if(StringUtils.isNotBlank(s) && new BigDecimal(s).compareTo(BigDecimal.ZERO) != 0) {
     b = true;
   }
} catch(NumberFormatException e) {
//swallow this exception; b stays false.
}

return b;
6

Empty catch blocks are a code smell in most languages. The main idea is to use exceptions for exceptional situations and not to use them for logical control. All exceptions must be handled somewhere.

As a consequence of taking this approach, when you program one particular application layer, you have several choices:

  • do nothing about the exception. It will be caught and handled by a different layer
  • catch it and perform the corrective action.
  • catch it, do something, but re-throw it for another layer to handle

This doesn't really leave any room for do-nothing, empty catch blocks.

EDITED TO ADD: suppose you are programming in a language where throwing exceptions is the normal way of controlling the program logic (one of alternatives to goto). Then an empty catch block in a program written in this language is very much like an empty else block in a traditional language (or no else block at all). However, I believe this is not the programming style recommended by C#, Java or C++ development communities.

  • I think using exceptions as logic control has become fairly common, so I find myself with empty or nearly empty catch blocks quite often. – whatsisname Nov 4 '10 at 16:18
  • +1 for recognizing that an empty catch block could indicate use of exceptions for flow control. – John M Gant Nov 4 '10 at 16:57
  • Using exceptions for programming logic is generally considered to be bad practice. But, surprisingly (my original argument against exceptions) exceptions don't incur a noticeable performance hit. See codeproject.com/KB/exception/ExceptionPerformance.aspx. – Evan Plaice Nov 20 '10 at 1:42
  • I think your wording is a bit strong. There are legitimate scenarios where exception catches need no code. 1) An exception happened, the JWT couldn't be expired on logout; 2) Do nothing because the session is cleared locally and there is a hard 10 min timeout on tokens on the remote API; 3) No need to halt the code with a message to the user as their token will expire in 10 mins max and their session cleared locally means they are logged out; 4) It was already logged to error log up stream (service or other class) – James Jul 27 at 10:06
6

In some cases, Java requires you to handle an exception that can, under absolutely no circumstances, ever happen. Consider this code:

try {
   bytes[] hw = "Hello World".getBytes("UTF-8");
}
catch(UnsupportedCodingException e) {
}

Every implementation of the Java platform is required to support the following standard charsets.

...

UTF-8

Without breaking your Java platform, there is simply no way to ever cause this exception. So why bother handling it? But you cannot simply ommit the try-catch-clause.

3

In some cases, the exception is not at all exceptional; in fact, it is expected. Consider this example:

    /* Check if the process is still alive; exitValue() throws an exception if it is */
    try {
        p.exitValue();
        processPool.remove(p);
    }
    catch (IllegalThreadStateException e) { /* expected behaviour */ }

Since there is no isAlive() method in java.lang.Process(), about the only way to check if it is still alive is to call exitValue(), which throws an IllegalThreadStateException if the process is still running.

| improve this answer | |
2

In my humble experience, rarely is this good thing. You mileage may vary though.

Nearly every time I've seen this in our code base, it's been because I've tracked down a bug that the eaten exception has hidden. To put another way, by not providing any code, the application has no way of indicating an error, or performing another action.

Sometimes, at API layers for example, you might not want or be able to let exceptions past, so in that case, I tend to try and catch the most generic, then log those. Once again, to at least give a debug/diagnosis session a chance.

Typically, if it must be empty, the least I do is put an assertion of some kind, so at least something happens during a debug session. That said, if I can't handle it, I tend to omit them completely.

2

IMO there is one place where empty catch statements are OK. In test cases where you expect an exception:

try
{
   DoSomething(); //This should throw exception if everything works well
   Assert.Fail('Expected exception was not thrown');
}
catch(<whatever exception>)
{
    //Expected to get here
}
| improve this answer | |
  • +1, I hate that I do this but it works in JUnit – sal Nov 4 '10 at 18:06
  • @sal: what about @Test(expected=Exception.class) ? – ysolik Nov 4 '10 at 18:22
  • @ysolik, bad habit – sal Nov 4 '10 at 18:32
  • 1
    @sal: Why is that a bad habit? – Adam Lear Nov 4 '10 at 19:04
  • ummmm. there are ways to do this with unit testing frameworks. Ex. NUnit. There are certain cases where testing that something predictably fails may be useful. Although, I would never do it in production code. – Evan Plaice Nov 20 '10 at 1:36
2

I believe there are certain cases where it is justified to have an empty catch clause - these are cases when you want the code to just keep going if a particular operation fails. However, I do think that this pattern can be easily overused, so each use should be closely examined to make sure there's not a better way to handle it. In particular, this should never be done if it leaves the program in an inconsistent state or if it could lead to some other part of the code failing later on.

| improve this answer | |
1

I don't believe in not having some level of alert when an exception occurs - shouldn't one of the goals of programming be to improve code? If an exception occurs 10% of the time, and you never know about it, then the exception will always be that bad, or worse.

However, I do see the other side, that if the exception does no real harm in the processing of code, then why expose the user to it. The solution I typically implement is having it logged by my logger class (that is in every single class I ever write at work).

If it's a benign exception, then I make a call to my Logger's .Debug() method; otherwise, Logger.Error() (and (maybe) throw).

try
{
   doWork();
}
catch(BenignException x)
{
  _log.Debug("Error doing work: " + x.Message);
}

By the way, in my implementation of my logger, making a call to the .Debug() method will only log it if I my App.Config file specifies that program execution log level is in Debug mode.

| improve this answer | |
  • What if _log.Debug throws an exception (for whatever reason)? – JohnL Nov 4 '10 at 19:19
  • Then .Debug() eats the exception and I never know about it. But I feel a lot more confident about my logger than I feel about code that often throws exceptions. If I were concerned about that, I suppose I could implement some sort of pattern that watches for entry into the catch block, and saves it for later. In any case - point taken – Tim Claason Nov 4 '10 at 21:09
1

Existence checking is a good use case:

// If an exception happens, it doesn't matter. Log the initial value or the new value

function logId(person) {
    let id = 'No ID';
    try {
        id = person.data.id;
    } catch {}
    console.log(id);
}

Another case is when a finally clause is used:

 function getter(obj){}

 function objChecker()
   {
   try
     {
     /* Check argument length and constructor type */
     if (getter.length === 1 && getter.constructor === Function)
       {
       console.log("Correct implementation");
       return true;
       }
     else
       {
       console.log("Wrong implementation");
       return false;
       }
     }
   catch(e)
     {
     }
   finally
     {
     console.log(JSON.stringify(getter))
     }
   }

 // Test the override of the getter method 
 getter = getter;
 objChecker();
 getter = [];
 objChecker();
 getter = {};
 objChecker();
 getter = RegExp;
 objChecker();
 getter = Function;
 objChecker();

There is a proposal to allow the omission of the catch binding in ECMAScript which pertains to this and similar use cases.

References

| improve this answer | |
  • Another example: In nodejs, the fs.exists method (which returns true or false) is deprecated (nodejs.org/dist/latest-v10.x/docs/api/…) in favour of fs.access which throws an exception in case a file does not exist. If one wants to do something only if the file exists, the catch clause is totally unnecessary. – systemovich Jul 17 '19 at 6:01
0

The only time I've really needed to do something like this was with a logging class for a console app. There was a top-level global catch handler which emitted the error to STDOUT, logged the error to a file, then closed the app with a >0 error code.

The problem here was that sometimes, the logging to the file failed. Directory permissions stopped you from writing the file, the file was exclusively locked, whatever. If that happened, I couldn't handle the exception in the same way I had elsewhere (catch, log the relevant details, wrap in a better exception type, etc) because logging the exception details caused the logger to go through the same actions (trying to write to a file) which had already failed. When they failed again... You see where I'm going. It gets into an infinite loop.

If you drop some of the try {} blocks, you can end up with the exception appearing in a message box (not what you want for a silent config app). So in that method which writes to the log file, I have an empty catch handler. This doesn't bury the error since you still get the >0 error code, it just stops the infinite loop and allows the app to exit gracefully.

There's a comment of course, explaining why it's empty.

(I was going to post this earlier, I was just afraid of getting flamed into oblivion. Since I'm not the only one, though...)

| improve this answer | |
0

It is ok in situation when some sequence must be executed no matter what with most critical piece placed at the end.

For example. In motion control communication of host to controller. In emergency situations there is a number of preparation steps to abort movement, stop trajectory generation, decelerate motors, enable breaks, disable amplifier and after this you must kill bus power. All must happen sequentially and if one of steps fails rest of steps must be executed anyway even with accepted risk of damaging hardware. Say even if all above fails, the kill bus power must happen anyway.

| improve this answer | |
  • That doesn't mean you do nothing, just that what you do doesn't abort the flow. Catch your exceptions, save them in memory (no disk write delay), then kill the power in a finally statement. Then do what you will with the saved information. – Loren Pechtel Jan 1 '18 at 1:42
0

Closing out system resources gracefully to recover from an error

For instance. If you're running a service in the background that doesn't provide feedback to the user, you may not want to push an indication of the error to the user but you do need to close out the resources being used in a graceful manner.

try
{
    // execution code here
}
catch(Exception e)
{
    // do nothing here
}
finally
{
    // close db connection
    // close file io resource
    // close memory stream
    // etc...
}

Ideally, you'd use the catch in debug mode to catch errors and print them to the console or to a log file for testing. In a production environment, background services generally are expected to not interrupt the user when an error is thrown so the error output should be suppressed.

| improve this answer | |

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