views:

1213

answers:

20

I know it's evil, but I've seen swallowed exceptions in code written by a good programmer. So I'm wondering if this bad practice could have at least one positive point.

In other words, it is bad but why do good programmers, on rare occasions, use it?

try
{
    //Some code
}
catch(Exception){}
+5  A: 

Because sometime even good programmers make mistakes.

Either that or your opinion of a good programmer isn't the same as some (because a good programmer would have left some reasoning behind as to why the Exception was swallowed rather than something being done with the information).

Justin Niessner
It's not always a mistake, though. Almost always, yes, but not quite always.
Steven Sudit
Sometimes the reasoning is simply "I don't care about the exception".
Chris Lively
@Chris: Ok, but when you swallow all exceptions, you don't know what it is you're not caring about. Depending on the language, it may be something asynchronous and therefore unrelated to the code whose failure you don't mind.
Steven Sudit
+18  A: 

Looking in my own code, I found a place in my logging code where, after failing to write to a file and failing to write to the event log, it swallows the error as there is no place left to report it. That's one example: there aren't many others.

Steven Sudit
+1 Worst case scenario - love it. Similar to "There was an error creating the error report", except... worse? Probably best to at least give the user a warning. Failing to produce a file, failing to produce an error report, and then not warning the user seems like a Customer Support nightmare '~'.
Justian Meyer
Yes, I would definitely consider displaying something, if only it wasn't a Windows Service. Arguably, there are cases where, if you can't log, you should immediately kill the application. This was not one such case, however.
Steven Sudit
You are assuming you are a good programmer :)
Shadow
@Shadow: That would be a terribly unsafe assumption. Instead, I assume that I am a moderately competent programmer whose errors will be quickly noted and corrected by good programmers.
Steven Sudit
+1. As usual it boils down to what reasonable thing you can do with that exception. Sometimes you just have to swallow it.
sharptooth
A: 

Maybe because it won't catch but needs to be able to anyway. I can't think of any reason why to avoid some sort of handler, though.

Orbit
+9  A: 

I'd argue that a good programmer wouldn't do that without explaining it.

try
{
    //Some code
}
catch(Exception e) {
    // Explanation of why the exception is being swallowed.
}

I'm very unlikely to just silently swallow the base Exception class though, for any reason. I'd at least try to log the error.


Here's a concrete example that I just happened to run across today in my project. This is part of a JavaScript function that gets an XMLHttpRequest supported by the browser.

var XMLHttp = null;

if( window.XMLHttpRequest ) {
    try {
        XMLHttp = new XMLHttpRequest();
    } catch(e) {} // we've already checked that this is safe. 
}
else if( window.ActiveXObject ) {
...
}

Since the try is wrapped in an if...else if that checks the type of object to be created, it's safe to swallow the exception.

Bill the Lizard
+4  A: 

Yes, I use them quite often in exception cleanup code so that I don't mask the original exception.

For example, if your catch handler is trying to rollback a transaction and close a connection before rethowing the exception, there could be several reasons that the rollback/close itself could fail (since you're already in some busted up as a result of the original exception). So, may want to wrap the clean in a try block with an empty catch handler, basically saying "if something goes wrong in the cleanup, that's sort-of-OK, since we have bigger problems to report"

Mike Mooney
You might want to log that the cleanup failed.
Cameron MacFarland
Yes you may, or very well may not. It depends on the nature of your application.
Mike Mooney
If you do want to log a failure while handling another failure, it begins to get more than just a little bit tricky.
Steven Sudit
A: 

That's like asking why good people sometimes lie or oogle women?

No one is perfect.

Steve
"oogle women"? Is that like ogling a woman you've googled?
PSUnderwood
No...I always tell the truth, even when I lie.
dotjoe
Nice to know someone has a sense of humor.
Steve
A: 

I do it when an exception can't be handled effectively, it shouldn't impact the normal operation of the application, and/or it might represent a transient condition that is known but has little overall impact.

A simple example is logging. You don't need the app to blow up just because some logging information won't be saved to your backing store.

Another example might be where you have alternative means of handling the situations, like this:

private Boolean SomeMethod() {
   Boolean isSuccessful = false;
   try {
      // call API function that throws one of several exceptions on failure.
      isSuccessful = true;
   } catch(Exception) { }

   return isSuccessful;
}

In the above example, you may not have a fall back position, but you don't want it to filter up. This is ok for SHORT methods where the return value is only set to a successful status as the last step in the try block.

Unfortunately there are many calls that will throw exceptions instead of simply returning an error code or false condition in the result. I've also seen calls that throw more exceptions than what their documentation suggests which is one of the reasons why I'll put a catch all around them.

Chris Lively
+1 It's said that are so many broken APIs around. At our university, people are often told to throw exceptions in places where returning a boolean e.g. would be much more approriate - and not only do they throw exceptions, they throw checked exceptions which often can't be recovered from.
Helper Method
@Helper Method: We have a couple rules regarding exceptions. First, if you can handle it, then it's not an exception. Second, all of our methods have a success/failure code as the result. Third, the ONLY time an exception should ever be thrown is if it represents a real system failure. For example, in a web app, the database server is offline. That would be okay.
Chris Lively
Why not try{ return true;} catch(Exception e) {return false;} ??
Daniel Moura
@Daniel: That's certainly an option, but if I have a fairly short method, say less than 10 lines, then that's just more typing with very little to no benefit.
Chris Lively
A: 

Even if it's just because nothing can be done with it, it'd still be nice to have comments. However, in ongoing custom/vertical apps with a stable team, sometimes those niceties go away if the reasons are at all obvious in the preceding code.

Brian Knoblauch
A: 

I won't say that I'm a good programmer but I have a good example why sometimes it is ok to swallow an exception, in my case it is part of the behaviour of the program.
example:

public void Load()
{
    try
    {
        using (System.Xml.XmlReader stream = System.Xml.XmlReader.Create(fileName))
        {
            XmlSerializer xs = 
                new XmlSerializer(typeof(List<Contact.Contact>), types.ToArray());
            List<Contact.Contact> data = 
               (List<Contact.Contact>)xs.Deserialize(stream);
            this.Clear();
            this.AddRange(data);
        }
   }
   catch (System.IO.FileNotFoundException)
   {
       // do nothing; no file, new database
   }
}

If XmlReader doesn't find a file it's ok, we just start over.

Gorgen
You're using exceptions to control the flow of the program. That's a bad idea.
Malfist
Ah, but this isn't swallowing all exceptions, just failing gently on a very specific one. Not saying it's bad, just that it's also not what this question is really about.
Steven Sudit
@Malfist: You could argue that they should check File.Exist first, but if the file is expected to always be there, then being missing would be an exceptional condition, and therefore this would be appropriate. The only thing I don't like about it is that it doesn't return `false` and/or log something somewhere.
Steven Sudit
@Steven: "I know that's evil, but I've seen swallowed exeption in code written by a good programmer." The original poster didn't mentioned swallowing all exceptions?
Gorgen
If it's expected the file to always be there than this would be an exceptional case and an exception should be thrown, not swallowed. However it seems as if the file is not always excepted to be there (in the case of a new database), therefor it is not exceptional, just not common.
Malfist
@Gorgen: They did in their sample code.
Steven Sudit
@Malfist: Whether to propagate an exception depends on the application's requirements. Silent failure can be the right answer. Having said that, there are different levels of silence, and logging barely counts as a whisper.
Steven Sudit
@Steven: Good point with File.Exist
Gorgen
@Steven: Aha, not an exception but Exception
Gorgen
@Steven Sudit: Checking with File.Exist() before opening has a small chance for a race condition. So I prefer to do both: check with File.Exists(), and handle FileNotFoundException somehow.
Sjoerd
@Sjoerd: Absolutely. Just because a file once existed doesn't mean it exists now. Besides, there are plenty of other errors possible, such as being able to tell it exists but not having the right to read from it. It could be argued that, since the file is expected to "always" be there, a check for existence is a bad idea.
Steven Sudit
+1  A: 

Without claiming to be a good programmer, I can at least explain why I sometimes catch and ignore. There are times when what I'm working on has to deal with an exception to compile, but is not the appropriate place to actually handle the exception. For instance, I was recently working in a program which parses a good deal of XML as one of its tasks. The actual XML parser opened a file, which generated an exception. The XML parser was not the best place to generate a dialog informing the user of bad file choice, though. Rather than get sidetracked with throwing the exception to the right place and handling it there, I silently caught the exception, leaving a comment and TODO (which my IDE tracks for me). This allowed me to compile and test without actually handling the exception. Sometimes, I will forget to take care of the TODO immediately, and the swallowed exception sticks around for a while.

I know this is not the best programming practice, and I certainly am not an expert programmer, but I think this is an example of why someone would want to do this.

Zoe Gagnon
Temporarily swallowing exceptions during development is a different matter than releasing code that swallows.
Steven Sudit
Yeah, in this case, they're catching and ignoring, not catch-and-rethrow.
Dean J
+12  A: 

Because sometimes the programmer has more knowledge than the compiler.

E.g. (in some fictional language where division by zero is regarded as an error):

try {
    x = 1 / (a*a + 1);
} catch (DivisionByZeroException ex) {
  // Cannot happen as a*a+1 is always positive
}

As some languages (e.g. Java) require to catch some/many/all exceptions, the compiler might complain while the programmer knows it is not possible. Sometimes the only way to get the compiler to shut up, is to explicitely swallow the exception.

In languages where the compiler doesn't complain, the empty catch usually is not written at all.

Edit: In practice, I would add an assert(false) in the catch block. If theoretically something cannot happen, it is a very serious problem when it does happen in practice ;)

Edit2: Java only requires to catch checked exceptions. Reworded my statement a bit.

Sjoerd
Java doesn't require you to catch ALL exceptions (only the checked ones), nor are you able to catch all.
Helper Method
(Assuming `a` is not `NaN`, of course)
jleedev
@HelperMethod: I've reworded my statement a bit.
Sjoerd
(And assuming it's not a complex number.)
Steven Sudit
@Helper Method You still need to catch all the non RuntimeException such as InterruptedException even if your code doesn't have any interrupt call anywhere.
HoLyVieR
I would not put the assertion in the `catch` block, but at the start of the function.
detly
... and assuming there is no numeric overflow. I think your example shows clearly that the supposedly impossible is often possible, and hence rudimentary exception handling should not be ditched.
meriton
@meriton: A numeric overflow won't result in a DivisionByZeroException or any of its childs. At least not in any well-designed exception tree.
Sjoerd
There are many programming languages where a numeric overflow does not result in an exception at all, but the high bits that don't fit the result datatype are simply discarded. Therefore, you'd actually have to prove that there is no x such that (x*x+1) mod 2^32 = 0, which is decidedly non-trivial...
meriton
@Meriton: It's not that hard to prove for a human: Note that x*x mod 4 = 0 or 1 (and never 2 or 3). So x*x + 1 mod 4 = 1 or 2 (and never 0). It might be hard for a compiler, which was exactly the point I wanted to make.
Sjoerd
You're right. (It's been a while since I needed modulo arithmetic.)
meriton
A comment to explain this would have helped, of course :)
Sjoerd
A: 

at the very least write it to the output window

try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}
fishhead
A: 

I needed to do this once, because an old framework threw senseless exceptions in rare cases, which I didn't care about. I just needed it to run in the cases that worked.

Blub
A: 

I've done this when there some is some piece of code where regardless of it failing I want the program to continue. For example I've opened an optional log file and regardless of why it failed to work I want to continue the execution of the program.

Even so though, it's not good code as you can get exceptions like out of memory exceptions that ignoring makes no sense at all so even though i've done it, it's still not the best idea and I wouldn't admit to doing it in public. (oops...)

I've done it on programs that are intended to be run once to convert some data or something just to shut the compiler up. That's an entirely different situation to any form of production code though.

Basically there is no good reason for doing this other than lazyness.

John Burton
A: 

How about when performing a progress-control update? I've updated the state variables used by a control's drawing routine, so the next time the control is drawn it will show the proper state. I then perform:

  Try
    MyControl.BeginInvoke(MyControlUpdateDelegate);
  Catch Ex as Exception
  End Try

If the control still exists, it will update. If it gets disposed, I won't care whether it gets updated or not. If the control isn't disposed, but can't be updated for some other reason, I still won't really care whether it gets updated or not because I'm not apt to be able to do anything sensible about it anyway.

Note that I could add "If Not MyControl.IsDisposed Then..." but that would just add work to the common case, and wouldn't prevent the exception from occurring if the control gets disposed during the BeginInvoke.

supercat
This would be better if you caught the specific exception that is expected.
Steven Sudit
@Steven Sudit: It would most likely be an ObjectDisposedException, but I don't know that there wouldn't be some variation on hide, minimize, etc. which wouldn't dispose the object but would prevent BeginInvoke from working. It seems more likely that I'd get an unanticipated exception from a situation where stuff should keep working, than from one where everything should die.
supercat
That's an entirely valid point, and may well win on practicality. The downside is that some other exception may occur, and you'd lose it. That's why logging this at the warning level may be a good idea.
Steven Sudit
If some human were actually going to look at logs, I suppose that generating a log when something other than an ObjectDisposed exception occurred might be good (an ObjectDisposed exception is sufficiently expected and unavoidable as to not be worth logging) simply to get a list of what other exceptions might rarely occur. If an application is going to be used by non-technical end-users, though, what would be accomplished by logging such exceptions in the release build?
supercat
@supercat: If you want a reply, please prefix my name the way I just did with yours. Anyhow, you never log for purely non-technical users. And when you log *due* to an exception, you always log the exception itself, including its inner exception chain. The easiest way is `ToString`.
Steven Sudit
@Steven Sudit: I try to prefix names (see above) but sometimes I forget. Suppose that one day when a user is running my application they close a control at just the right time to cause the BeginInvoke to hit some other exception. Should I throw a pop-up that says "Don't panic, but please convey the following to the author of the program somehow" or what?
supercat
Ideally, we would know all of the exceptions that could be caused by premature cancellation and catch them all. But there's no guarantee of this. Instead, when we catch the rest of the exceptions, we could throw them as inner exceptions, where the top-level one has an appropriate message, such as "Unable to complete task due to interruption".
Steven Sudit
@Steven Sudit: The situation I'm concerned about is when an observer window is closed for an object which exists for reasons other than display in that window. The object being observed should continue to exist and do whatever it was doing without regard for whether or not a particular observer window is open. Closing the window shouldn't interrupt the task at hand.
supercat
Maybe the solution doesn't involve ignoring exceptions, though.
Steven Sudit
@Steven Sudit: What would it involve doing? The desired semantics are "if this control works, update it; if not, it's probably not worth updating".
supercat
I was hinting at the idea that the solution would to avoid the original problem. This is essentially just a race condition.
Steven Sudit
@Steven Sudit: It is indeed a race condition, but one which so far as I know has no solution other than to swallow the exception (and I have no idea how to be certain of what exceptions I might get as a result of the race). I can't guarantee that anything that disposes of my viewer control will acquire any particular lock before doing so, and I can't do my BeginInvoke from the control's thread because the only non-blocking way to sequence code for a control's thread is to use BeginInvoke.
supercat
I'm thinking that, rather that there really must be some way to tell if the control is still alive, even if it means doing some sort of synchronization. For example, the invoke could be wrapped in a lock, while the handler that closes that window could likewise wait on that lock. This way, the window only gets closed *after* the message goes through. Am I completely nuts?
Steven Sudit
@Steven Sudit: For that to work, it would be necessary to have control over anything that might dispose the window. I suppose I could override the Dispose method and replace it with one that acquires a lock, sets my own dontUseAnymore flag, releases the lock, and then calls the old Dispose, but that seems worse than simply swallowing exceptions from BeginInvoke. Of course, a TryBeginInvoke function would have avoided the whole problem.
supercat
@supercat: Oh, I wasn't suggesting it should set any additional flags (other than whatever it uses to tell it was already disposed). My point is that `Dispose` is run exactly once, so serializing it with regard to that delegate sounds like the *correct* way to avoid the problem. Having said that, yes, it does sound difficult to retrofit the infrastructure.
Steven Sudit
A: 

Due to the nature of the applications I write, virtually every exception I catch needs to be logged to a file.

Exceptions should never be eaten without any kind of rethrow, logging, or even a comment explaining why the exception was silently eaten. In my earlier years I would often eat exceptions if I knew that I was the only person working on the code. Of course when it came time to revisit the code I would forget what that exception really meant, and I'd have to retest everything to figure it out again.

baultista
A: 

I find silent exception handling works great for AJAX routines when alerting the user or handling the exception might bomb the code. Javascript can be so moody, its sometimes best to let it run its course knowing what it will do differently on errors.

try
  {
  var result1=ajax_loop(field1,type1,field2,user_id,xsrf); 
  }
finally
  {
  if (result1==0)
    {
    setTimeout( "redirect();", 3*1000 );
    } 
  }

Notice there is no catch in this example. This is done purposely as any exception simply retries the AJAX when the result is zero.

Talvi Watia
A: 

I can only think of two kinds of cases where I've swallowed exceptions.

  1. When closing files or database connections. If I get an error on the close, what am I going to do about it? I suppose I really should write out some sort of error message, but if I've already successfully read the data, it seems superfluous. It also seems like a very unlike event to happen.

  2. More justified: Inside error handling. If I fail trying to write to the log file, where am I going to write the error that says that I couldn't write an error? In some contexts you could try to write to the screen, but depending on the app, that might be impossible, e.g. a background job with no screen; or just confusing to the user who won't be able to do anything about the error anyway.

Another poster mentioned cases where you know the exception is impossible, or at least, that for it to happen there would have to be major problems with your compiler or operating environment, like it did not add two numbers together correctly, in which case who says the exception is meaningful?

I heartily agree that in these rare cases where it is legitimate, you should include a comment to explain why the exception is irrelevant or impossible. But then, I'd say that anytime you write code that is potentially cryptic, you should include an explanatory comment.

Side note: Why is it that programmers routinely include comments like "x=x+1; // add 1 to x", like duh, I never would have digured that out without the comment, but then throw in really cryptic code with no explanation?

Jay
+2  A: 

Because something has to be finished for a presentation the boss spontaneously does tomorrow and nothing is worse than the program crashing or showing a nasty error message, while when something is just not working he can always "talk around" that.

After the presentation, no one will improve those "quick fixed" parts of course. ;-)

herzmeister der welten
A: 

I believe it's because of Java's checked exceptions. I personally hate them because of this because people tend to think they need exception-handling code everywhere. IMO in 99% of the code you should just be throwing your exception up the stack and not handling it. I'd be happy if the default signature for any new method created had 'throws Exception' in it so that I don't have to deal with exceptions unless I want to.

IMO you only need exception-handling in two places: 1. For resource cleanup like closing an input stream, database connection or deleting a file. 2. At the very top of the stack where you catch the exception and either log it or show it to the user.

There are places where you really don't need to do anything in the catch such as handling the InterruptedException from Thread.sleep() and there you should at least have a comment to make it clear that you really don't want anything to happen there.

sjbotha