Wow, I just got back a huge project in C# from outsourced developers and while going through my code review my analysis tool revealed bunches of what it considered bad stuff
Generally no, in fact no in 99% of all cases, BUT
There are exceptions. One one project I worked on we used a third party library to handle a TWAIN device. It was buggy and under some hardware combinations would throw a null pointer error. However we never found any circumstances when it didn't actually manage to scan the document before it did that - so catching the exception was entirely rational.
So I think if it's your code that's throwing the exception then you should always check it, but if you're stuck with third party code then in some circumstances you may be forced to eat the exception and move on.
While there are some reasonable reasons for ignoring exceptions; however, generally it is only specific exceptions that you are able to safely ignore. As noted by Konrad Rudolph, you might have to catch and swallow an error as part of a framework; and as noted by osp70, there might be an exception generated by a framework that you know you can ignore.
In both of these cases though, you will likely know the exception type and if you know the type then you should have code similar to the following:
try {
// Do something that might generate an exception
} catch (System.InvalidCastException ex) {
// This exception is safe to ignore due to...
} catch (System.Exception ex) {
// Exception handling
}
In the case of your application, is sounds like something similar might apply in some cases; but the example you give of a database save returning an "OK" even when there is an exception is not a very good sign.
I think that if you have an empty catch block you need to document why it is empty so that the next developer will know. For example on server.transfer a web exception is sometimes thrown. I catch that and comment that we can ignore it because of the transfer call.
I wonder about this specific one a lot.
Connection con = DriverManager.getConnection(url, "***", "***");
try {
PreparedStatement pStmt = con.prepareStatement("your query here");
... // query the database and get the results
}
catch(ClassNotFoundException cnfe) {
// real exception handling goes here
}
catch(SQLException sqle) {
// real exception handling goes here
}
finally {
try {
con.close();
}
catch {
// What do you do here?
}
}
I never know what to do in that last catch in the finally block. I've never seen close() throw an exception before, and it's so unlikely that I don't worry about it. I just log the exception and move on.
There are certainly circumstances where it's OK to catch a specific exception and do nothing. Here's a trivial example:
public FileStream OpenFile(string path)
{
FileStream f = null;
try
{
f = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
}
catch (FileNotFoundException)
{
}
return f;
}
You could also write the method this way:
public FileStream OpenFile(string path)
{
FileStream f = null;
FileInfo fi = new FileInfo(path);
if (fi.Exists)
{
f = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
}
return f;
}
In this case, catching the exception is (very) marginally safer, as the file could get deleted between the time you check for its existence and the time you open it.
There are reasons not to do this, sure. In .NET, exceptions are computationally expensive, so you want to avoid anything that throws a lot of them. (In Python, where exceptions are cheap, it's a common idiom to use exceptions to do things like break out of loops.)
But that's ignoring a specific exception. This code:
catch
{
}
is inexcusable.
There's no good reason not to catch the specific typed exception that the code in the try
block is going to throw. The first reason that the naive developer gives for catching exceptions irrespective of type, "But I don't know what type of exception might get thrown," is kind of the answer to the question.
If you don't know what type of exception might get thrown, you don't know how your code can fail. If you don't know how your code can fail, you have no basis for assuming that it's OK to just continue processing if it does.
Unless your catch code will either
You can ignore the exception, but at least mention the expected exception in the method docs, so the consumer can expect and handle if necessary