It's generally a good practice to not handle runtime exceptions.
I have this scenario :
/**boolean returns false if the method execution fails,
so that an error can be shown to user*/
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}
catch(Exception e)
{
//Log the exception and return false
return false;
}
return true;
}
So from the Servlet calling it will get a boolean value. If it's false, we show a message 'Save Not sucessful'. Is this okay or is there a better way of doing it ?
Is it okay to handle Runtime exceptions?
As long as you can do something intelligent at that point, yes. This 'never catch run-time exceptions' is pure nonsense. You'll probably want to log them and do other things, as well.
It's generally a good practice to not handle runtime exceptions.
This sentence implies a false premise: the question is not whether, but when to catch runtime exceptions.
At some point in your code you should definitely have a "catch-all" exception handler. This point is called the exception barrier, and it is high enough in the call stack to encompass a complete unit of work (basically, the scope of one database transaction).
This should be your governing principle:
if an exception must cause the current unit of work to be aborted (rolled back), then do not catch that exception until the exception barrier;
if an exception is of local character only, and its appearance only means taking a different route to the handling of the request, then do catch and handle it early.
Note that the above doesn't use the fruitless checked/unchecked distinction. Most modern frameworks completely avoid checked exceptions and go out of their way to shield the programmer from such exceptions being thrown from lower-level code.
In practice, more than 90% of all exceptions are of the first, aborting kind. This is what is meant by the term "unrecoverable"—it means you can't continue what you are doing right now, but the server can stay up and process all other requests. I see many people confusing this with "the JVM is about to die", but exceptions which have that meaning are exceedingly rare and usually there is no special handling code for them.
Lastly, note that the "catch-all" handler should catch not only RuntimeExceptions but also Errors because you want every exception logged the same way. If you let an exception escape your application code, there is no knowing what behavior it will cause. Note that there are some common errors, like StackOverflow and OutOfMemory, which can in principle cause unrecoverable damage and therefore rightfully belong to the Error hierarchy, yet in most real-life cases do no damage beyond aborting the current request. You definitely do not want to shut down your service at the first sight of such an error.
No, catching a general Exception will mask any other problems you don't want to catch. Better catching specific exceptions making it harder for unexpected ones to go missing.
I guess your question has two aspects: 1) Handling RuntimeExceptionas the heading suggested and 2) handling generic Exception these are two different things.
The Javadoc of RuntimeExcepton list a bunch of its subclasses (NullPointerException..etc). If you look carefully, these are nothing but the programming errors and instead of handling them in catch block, should be corrected the the code itself so that they do not occur.
Handling generic Exception is generally referred as a poor practice and rightly so because it hides the specific exceptions which might need different handling.
But in case similar to yours, if there is a Servlet giving a call to method there has to be a graceful way to tell the user that there was some problem with the application while processing the request instead if showing the stacktrace.
So what you are doing could be one way of handling and as a good practice keep track of errors/exceptions in the log and correct any RuntimeExceptions
boolean returns false if the method execution fails,
so that an error can be shown to user
This is a clear reason for the method to throw an exception. It is why the exception mechanism exists in the first place. Best practice is to use exceptions for these types of circumstances, not boolean signals.
Anytime you follow this kind of pattern, you suffer in several ways
The caller cannot be sure what really happened. Was there a communication failure? Was the data corrupted? There is no way to tell when you return a simple "FAILED" signal.
Because the caller cannot know what happened, you take away options for the caller. Maybe the caller could do something in certain error cases.
You increase the potential for data errors. Again, since the caller cannot know why it failed, the caller may make assumptions about why it failed and continue in cases when the entire program should halt. If the program continues, it may decide to process invalid data when it really should stop.
I highly recommend reading the sections on exception handling in Effective Java. Basically, if you can't do anything meaningful with an Exception in your method, you should allow it to pass up the stack. In the worst case scenario, the API you reference throws a generic checked exception, giving you one of three choices (EDIT: Changed to void return type because the boolean return type no longer has any meaning -- you either succeed or throw an exception)
-Create your own.
// "MyFatalException" would be a checked Exception
public void saveData() throws MyFatalException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new MyFatalException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
}
-Throw an existing type (my preference is for subclasses of RuntimeException)
public void saveData() throws IllegalStateException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new IllegalStateException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
-Declare to throw a generic Exception and let it pass up (I do NOT recommend this, but you'll see many developers who do this)
public void saveData() throws Exception{
// no try/catch needed. Just make the call
}
The general concept is that frameworks or APIs would throw a RuntimeException only in situations when the error is not recoverable in code. e.g: your Db is down, or your server socket is down and things like that.
Though its not bad to catch such exceptions but whats actually thoughtful is what do you intend to do after catching them. e.g: people prefer to catch DB level connection problems and errors which are runtime exception subclasses and show error pages on their websites. Checked exceptions are usually for code level situational cases and catching them and handling is what code is expected to do.
In case you try something like this, since you don't want your users to error page you can do this, provided you caught all other exceptions before this.
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}catch(db_Connectivity_Exception e){
//exception like credentials invalid
}catch(db_table_Exception e){
//table desc. changed
}
catch(Exception e)
{
//Log the exception and return false
//Since you are going to log your error I hope is not harmfu
return false;
}
return true;
}
Still this is not best practice
Related
I am a fresher, and after successfully completing my project I scanned it through fortify. it gave me a list of issues, out of which just one categories remain. (Fortify a code quality scanning tool)
it says, "Not to use Broader Exception i.e. System.Exception" to catch exceptions unless in some conditions.
But I have a few methods that have 25-30 lines of code with different types of operations, in such case how to figure out which all specific exceptions to catch.
Should we also throw all these exceptions to be caught at a higher level catch, as i read "throw first catch late".
Please suggest me a clean way to do this.
e.g.
public SomeMethod(arg) throws IOException,SQLException,beanNotFoundException {
try {
someCode
} catch (IOException|SQLException|beanNotFoundException ex) {
logger.log(ex);
throw ex;
}
}
But also if i don't use Exception Class altogether till the end, i also have to make sure that I am not missing any exception to handle.
Is there a better approach.
Static Analysis
First and foremost, let me start with a little fallacy that most people fall subject to (and I see a lot in the corporate world): Static analysis tools are not infallible. They make mistakes. There are some warning classes that, with all the computing power known to man and with the remaining lifespan of the universe, the tool may not be able to exhaustively analyze a piece of code related to a particular warning class. Moreover, there are some warning classes that can complete before the end of time, but would be unreasonable to expect you to wait 7 days for an answer for one warning on one section of code for one execution path. That is, static analysis tools have to make guesses sometimes. The better tools are better at making guesses (you pay for what you get), but in the end, they are all capable of guessing right (true positive/negative) or wrong (false positive/negative).
Additionally, some warning classes may be applicable and some may not be. Some other warning classes may be important to you and some may not be. For example, PMD has a warning class to the effect of "Unused Import". An unused import has no effect on runtime, and while it may not be ideal, you can leave it in your code and it will not affect you unless your codebase is large and requires time to compile, and you have lots of these (unused imports make it longer to build your project). I particularly mention static analysis, because it sounds like you ran Fortify on your codebase and fixed anything and everything without questioning the validity. Most of the time it will probably be right, but just don't take it as fact because it told you so. You need to question whether these tools are always right.
Your example
So your example is not a false positive. If you do
throw new Exception("");
that's generally not what you want to do. It's fine for debugging and just quickly throwing code together. But, as your codebase gets larger, handling Exceptions will get more difficult.
This leads me right into my next point. You make the statement
But I have a few methods that have 25-30 lines of code with different types of operations, in such case how to figure out which all specific exceptions to catch.
...
But also if i don't use Exception Class altogether till the end, i also have to make sure that I am not missing any exception to handle.
Which seems to indicate to me that you either have something to the effect of
try{
//25-30 lines of code
} catch (Exception ex) { /*ex.printStackTrace(); Logger.getLogger(...).log(...); etc etc...whatever it is you do here, or maybe nothing at all*/
This is pretty bad - in most cases.
To get back to answering your question before I explain why, yes, you should absolutely catch each individual exception. The reason for this, and why your catch all is bad, is because if there is something specific that goes wrong, you can't have a specific type of error handling.
For example, take a function Foo#bar(java.lang.String), which throws an IOException when a disk access fails because you tried to write to a bad file, a BooException if you pass in a String without a special character in it, or a BazException for some other arbitrary reason. Now let's go back to your example from above: what if I wanted to realize that the file I was writing to was bad, and maybe prompt the user for some clarification before I moved on? What if I knew that if a BooException was thrown, that the user should have never been here in the first place, and I need to redirect them to some location? What if I knew that when a BazException that the system was out of sync with some other system and that this is a fatal problem, and now I need to do resource cleanup before I forcefully crash the JVM?
The above reasons are why you should do individual try/catch blocks for each statement and each exception.
That being said, there are reasons to not do this. Imagine, with the above example, that all you want to do for a IOException, BooException and BazException (and also any runtime exceptions, i.e. NullPointerException) that I just want to log the exception and move on. In this case, I would say it's OK to do a try/catch around a block of code - so long as it's just around the code that this applies to.
EDIT: You made a point about missing an exception, but putting a response to that in the comments seemed unruly to look at. In any case, let me start off by saying if it is not a runtime exception, then you will not even be able to compile without handling it. Catching Exception catches everything, runtime or not, which is how you compile now. From my example above, if there are runtime exceptions you are worried about missing, instead of just starting off with catching Exception:
Foo myFooInstance = new Foo();
String someValue = "value";
try {
myFooInstance.bar(someValue);
} catch (IOException ioe) {
/*handle file access problem*/
} catch (BooException boe) {
/*handle user in wrong spot*/
} catch (BazException bze) {
/*handle out-of-sync fatal error*/
} catch (Exception ex) {
LogRecord lr = new LogRecord(Level.SEVERE, "Unhandled exception!! returning immediately!!");
lr.setThrown(ex);
lr.setParameters(new Object[]{someValue});
Logger.getLogger(MyClass.class.getName()).log(lr);
return;
}
Here you end with your catch-all rather than starting with it. Think of it as your last-ditch effort to try to handle everything. It may not mean the exception is fatal to your program, but you probably shouldn't continue either (hence why my example uses return;)
Another small thing to consider, is that it becomes exponentially more difficult for the JVM to catch the exception properly the larger the try block gets (if the exception is never thrown, there is no overhead). This is more trivial to powerful machines, but something to keep in mind. With that in mind, I also don't have any sources for performance about exceptions being thrown in large try blocks, so take that with a grain of salt unless somebody finds something and mentions it.
In general, you only need to worry about handling/throwing checked exceptions. A clean way to write the method depends on the code base and structure of your application. Here are some alternatives:
If you want the client code (code calling someMethod) to handle the exception, you can do this:
public void someMethod(String arg) throws IOException, SQLException,
BeanNotFoundException {
doSomething(arg);
}
If you can handle the exception locally in someMethod, do so, but do not rethrow the same exception up in the call stack:
public void someMethod(String arg) {
try {
doSomething(arg);
} catch (IOException | SQLException | BeanNotFoundException ex) {
logger.log(ex);
handleException(ex);
}
}
If the exception is something you cannot recover from, and you don't want to enforce client code to handle the exception, you can wrap it as a RuntimeException. This will potentially terminate the program (which is usually what you want when a fatal error occurs):
public void someMethod(String arg) {
try {
doSomething(arg);
} catch (IOException | SQLException | BeanNotFoundException ex) {
logger.log(ex);
throw new RuntimeException(ex);
}
}
For a good explanation about checked vs. unchecked exceptions, you can refer to Java: checked vs unchecked exception explanation.
My advice would be to ignore what Fortify is saying. Or better still, figure out how to selectively suppress these warnings.
The alternative to your current version that Fortify is suggesting is objectively bad in most contexts. Your current version is not bad, only (a bit) verbose.
Another alternative would be to wrap the exceptions in a custom exception or exceptions that have a common custom checked exception as the base-class (NOT Exception or Throwable or RuntimeException). That could make code like you example neater, but it means that you need to add code (somewhere) to do the wrapping and (maybe) unwrapping. In short, that's no idea too.
OK so what is the problem with catching Exception? Well basically, it catches everything ... including any unexpected uncheck exceptions that are evidence of bugs. If you then declare the method as throws Exception it only gets worse.
I have seen an example (no names) where someone did this in a large Java product. The result is that the product's Java APIs are horrible to program against. Every non-trivial API method is declared as throws Exception, so someone programming against the APIs has no idea what to expect. And the code-base is proprietary and obfuscated. (And the worst thing is that the lead developer still thinks it was a good idea!)
What about wrapping the exceptions in RuntimeException? That's not quite as bad1 as Exception but the problem is that the programmer still can't tell what exceptions to expect.
1 - It is not quite as bad in the sense that throws Exception is effectively "noise" once you have gone done the path that anything can throw anything.
The general rule of thumb is that checked exceptions are thrown for errors that are external or unpredictable, and which the caller can reasonably be expected to do something about, even if that only means displaying a message to the user. Whether you catch them or pass them up the call stack depends on where it makes the most sense to handle them.
Unchecked exceptions are thrown for unsatisfied preconditions or invalid arguments. In other words, the programmer screwed up. That's why you're not forced to catch them; they're typically things that "shouldn't happen." You generally don't need to worry about them if you're using the API correctly. The only time you should catch unchecked exceptions is when an API doesn't follow these conventions and throws unchecked exceptions for external or unpredictable reasons.
Surprisingly google didn't describe any catastrophic scenarios my twisted mind craved for.
Anywhere I read, catching errors is discouraged. Basic rule seems to be that if your application produced error, it's already dead, beyond saving. So if you catch errors in your main function, does your program turn into zombie?
How can even error be caught if the program is already collapsing? Can catching errors do something real bad? Which errors are worst and which are sometimes caught? Could you describe a little test case that can produce the errors (like really produce them, not just throw them) so that I can see that they do if I catch them and ignore them?
Not much happens except that the thrown object is caught. Your process can be in a bad place, though, depending on what caused the error.
A StackOverflowError is pretty undramatic to catch - it's thrown when the maximum stack depth is exceeded, and since it then starts popping the call stack, it's no longer a problem (unless you try calling the offending method again).
class SO {
static int stackOverflow(){ return stackOverflow(); }
public static void main(String... args) {
try {
stackOverflow();
} catch (StackOverflowError e) {
System.out.println("Oh well, life goes on.");
}
}
}
Other errors, like OutOfMemoryError, are somewhat more problematic - there will still be too much memory used after it's been thrown. Some are directly fatal, like ClassFormatError, which means that you're trying to load a broken class file (and it's usually thrown in places where you can't catch it).
Other Errors are somewhere inbetween. AssertionError, for example, is thrown when a programmer-defined condition (like assert answer == 42;) isn't met, but only if you've enabled assertions.
Long story short, though: If you're catching specific errors, you're probably doing the wrong thing (unless you really know what you're doing!). If you're running a server app and want it to keep running, you're probably better of letting the current thread or process die and have it restarted by some kind of monitor.
Catching an Exception or Error is not a good idea, unless;
you can do something useful with it.
as a last resort to ensure it is logged correctly or in a submitted Runnable to an ExecutorService. In this case catching Throwable may be desirable.
Nothing terrible will happen if you catch an Error, however you can't pretend it didn't happen either (i.e. you can't just continue as if it didn't matter)
Note: not catching an error can be a bad thing for multi-threaded applications. This is because an uncaught error only closes the current thread. If there are multiple threads, they will keep running if at least one is not a daemon This can leave a program running but in a bad state.
I ask what happens.
Nothing special, you catch it and you can deal with it or log it.
Are you talking about catching Exceptions? There are two types of Exceptions checked and unchecked. The reason to catch an Exception as simple as catching a programmer defined Exception which enables the user to reenter the data. This normally applies to checked Exceptions.
Unchecked Exceptions cannot be recovered from and you might ask why catch them at all? Perhaps the developer wants to catch it to log the conditions which caused the Exception and to better troubleshoot the issue.
Here is an article discussing them both.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
This question already has answers here:
What issues may ensue by throwing a checked exception as a RuntimeException?
(6 answers)
Closed 9 years ago.
In Java it is observed that there is a convention of re-throwing a RuntimeException just after handling a Checked Exception.
This way has both good and bad consequences. When the compiler forces something to be handled via a Checked Exception, the developer can just get rid of it by catching it and re-throwing it as a RuntimeException.
Can someone explain if this scenario can be considered as a good practice? If so, would this approach be less error prone or would it make the code base unstable?
Actually it is the incompetent attempts at handling checked exceptions which result in an unstable code base. Typically, you'll have this:
try {
//stuff
} catch (IOException e) {
log.error("Failed to do stuff", e);
throw e;
}
and then next level up you'll have to deal with it again, typically logging it all over and making a mess of the log files. It will be even worse if you don't rethrow:
try {
// do stuff
} catch (IOException e) {
return null;
}
Now the calling code has no idea something went wrong, let alone what. Compared to those attempts, this actually accomplishes exactly what the application logic needs:
try {
// do stuff
} catch (IOException e) {
throw new RuntimeException(e);
}
Now the exception can freely propagate up the call stack until it reaches the well-defined exception barrier, where it:
aborts the current unit of work;
gets logged at a single, unified spot.
In a nutshell, to decide whether to catch-and-handle or catch-and-rethrow, just ask yourself this question:
Must the occurrence of this exception abort the current unit of work?
if yes: rethrow an unchecked exception;
if no: provide meaningful recovery code in the catch-block. (No, logging is not recovery).
From many years of real-life experience I can tell you that more than 90% of all possible checked exceptions are of the "aborting" type and need no handling at the place of occurrence.
Argument against the language feature of checked exceptions
Today, checked exceptions are widely recognized as a failed experiment in language design, and here's the key argument in a nutshell:
It is not up to the API creator to decide on the semantics of its exceptions in the client code.
Java's reasoning is that exceptions can be divided into
exceptions resulting from programming errors (unchecked);
exceptions due to circumstances outside of programmer's control (checked).
While this division may be real to some extent, it can be defined only from the perspective of client code. More to the point, it is not a very relevant division in practice: what truly matters is at what point the exception must be handled. If it is to be handled late, at the exception barrier, nothing is gained by the exception being checked. If handled early, then only sometimes there is a mild gain from checked exceptions.
Practice has confirmed that any gains afforded by checked exceptions are dwarfed by real-life damage done to real-life projects, as witnessed by every Java professional. Eclipse and other IDEs are to blame as well, suggesting inexperienced developers to wrap code in try-catch and then wonder what to write in the catch-block.
Whenever you encounter a method which throws Exception, you have found yet another living proof of the deficiency of checked exceptions.
The idea of checked exceptions is "Java only" - as far as I know, no language after Java adopted this idea.
There are too many checked exceptions which are caught ... and silently ignored.
If you look at Scala, they dropped it as well - it's only there for Java compatibility.
In this tutorial on Oracle's web site, you will find this definition:
If a client can reasonably be expected to recover from an exception, make it a checked exception.
If a client cannot do anything to recover from the exception, make it an unchecked exception.
This notion has been adopted in Scala as well, and it works fine.
Technically speaking your proposal works. Discipline and code reviews are required in either way.
The term "can just get rid of it" is not totally correct in this case. This is getting rid of exceptions:
try {
} catch (Exception e){
e.printStacktrace();
}
This is the most common bad practice among the try-catch use. You are catching the exception and then, just printing it. In this case, the catch block catches the exception and just prints it, while the program continues after the catch block, as if nothing had happened.
When you decide to catch a block instead of throwing an exception, you must be able to manage the exception. Sometimes exceptions are not manageable and they must be thrown.
This is something you should remember:
If the client can take some alternate action to recover from the
exception, make it a checked exception. If the client cannot do
anything useful, then make the exception unchecked. By useful, I mean
taking steps to recover from the exception and not just logging the
exception.
If you are not going to do something useful, then don't catch the exception. Re-throwing it as a RuntimeException has a reason: as stated before, the program just cannot continue as nothing happened. This way, a good practice would be:
try {
} catch (Exception e){
//try to do something useful
throw new RuntimeException(e);
}
This means: you just caught an Exception (like an SQLException) from which you can't recover without stopping and resetting the thread. You catch it, you try to make something in between (like resetting something, closing open sockets, etc...) and then you throw a RuntimeException().
The RuntimeException will suspend the whole thread, avoiding the program continue as if nothing have happened. Furthermore, you were able to manage the other exception without just printing it.
It may or may not be okay, depending on the context, but it probably is not.
As a rule of thumb RuntimeExceptions should only be used to indicate programming errors (examples include IllegalArgumentException and IllegalStateException). They don't have to be checked exceptions because you generally assume your program is correct until proven otherwise and you cannot handle these exceptions in a meaningful manner (you have to release an updated version of the program).
Another valid use of runtime exceptions is when you use a framework that will catch and handle the exception for you. In such a scenario it would only be burdensome to having to declare the exception in every method when you are not going to handle it anyway.
So generally speaking I would say re-throwing a checked exception as a runtime exception is very bad practice unless you have a framework that will handle it properly.
The general rule is: you throw a checked exception when the caller might be able to do some kind of recovery when informed about it. Otherwise, throw an unchecked exception.
This rule applies when an exception is first thrown.
But this also applies when you catch an exception and are wondering whether to throw a checked or unchecked exception. So there is no convention to throw a RunTimeException after catching a checked one. It is decided in a case-by-case basis.
One small tip: if you are going to just re-throw an checked exception after catching one and do nothing else, most of the time it is alright to just not catch the exception and add it to the exceptions thrown by the method.
I need to find out best-practice for try-catch when launching a new thread.
Personally, I prefer Option 2.
Which option is the best-practice? Are there any factors that might make either option a best practice in some situations and not others?
Option 1
public void run(){
try{
//do something
}catch(Exception e){
// log
}
}
Option 2
public void run(){
try{
//do something
}catch(Throwable t){
// log
}
}
EDIT: Assume that you are writing the code that has to meet a stringent code review.
EDIT 2: I know the difference between the above two options. I am just curious about what is seen as '100% correct' by others.
I would use setDefaultUncaughtExceptionHandler(...) on the thread to catch what the runnable does not handle properly, but when it comes to the runnable itself, it really depends on what it has to achieve and to reasonably anticipate considering a reasonable execution context.
On the other side, creating a separate thread to execute a runnable is not a good strategy IMHO, FutureTask deals with these issues better.
In a root exception handler that simply logs whatever went wrong, distinguishing between Error and Exception is pointless, so catching Throwable is perfectly acceptable.
If instead you were writing some retry logic, I'd catch Exception, since there really is no point retrying after an Error - in fact, it could be dangerous, because the error was thrown in code that was not exception safe, and thus might have left the system in an inconsistent state.
Therefore, it depends on what kind of exception handler you are writing.
It is never advisable to catch Throwable since this includes errors that cannot be handled or avoided such as out of memory error and so on. Thus it is generally much better to catch Exception and not catch Throwable. Sometimes it is unavoidable such as when calling invoke method or other reflection methods.
What you are trying to ask about is the concept of a fault barrier and the correct way to implement one should be a standard defined by the project you are working on or the framework you are using.
If your project has a policy to log all exceptions/errors and not let anything print to standard error, you might want to look into using an UncaughtExceptionHandler.
A general best practice would be to catch only instances of RuntimeException.
public void run(){
try{
//do something
}catch(RuntimeException e){
// log
}
}
Catching Exception is too general because the Java language requires programs to deal with checked exceptions. By catching even checked exceptions at your fault barrier you are allowing the code in the //do something block to be sloppy and not handle checked exceptions.
Catching Error or Throwable is also generally considered a bad practice since an Error typically indicates that the JVM is in a state where it can not continue to function meaningfully.
Here is a good (and somewhat relevant) article on exception handling: http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html
Why is the catch(Exception) almost always a bad Idea?
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
Short story: it's called bug masking. If you have a piece of code which is not working well and throwing exceptions (or you pass malformed input to that piece of code) and you just blind your eyes by catching all possible exceptions, you will actually never uncover the bug and fix it.
You should only catch exceptions if you can properly handle them. As you cannot properly handle all possible exceptions you should not catch them :-)
It depends on what you need. If you need to handle different types of exceptions in different ways then you should use multiple catch blocks and catch as much specific exceptions as you can.
But sometimes you may need to handle all exceptions in the same way. In such cases catch(Exception) may be ok. For example:
try
{
DoSomething();
}
catch (Exception e)
{
LogError(e);
ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
}
Because you don't really know why an exception happened, and several exceptions require very special car to be handled correctly (if possible at all), such as a OutOfMemoryException and similar low-level system exceptions.
Therefore, you should only catch exceptions:
which you know exactly how to deal with it (e.g. FileNotFoundException or so)
when you will re-raise them afterwards (for instance to perform post-fail cleanup)
when you need to transport the exception to another thread
I find two acceptable uses of catch(Exception):
At the top level of the application (just before returning to the user). That way you can provide an adequate message.
Using it to mask low-level exceptions as business ones.
The first case is self-explanatory, but let me develop the second:
Doing:
try {
// xxxx
} catch(Exception e) {
logger.error("Error XXX",e)
}
is bug masking like #dimitarvp said.
But the below is different:
try {
// xxxx
} catch(Exception e) {
throw new BusinessException("Error doing operation XXX",e)
}
This way you aren't ignoring bugs and hiding them under the carpet. You are providing a high-level exception with a more explanatory message to higher application layers.
It's also always important to manage exceptions at the correct layer. If you escalate a low-level exception to a high business layer, it's practically impossible for the higher layer to manage it well.
In that case, I prefer to mask the low level exceptions with a business one that provides a better context and message and that also has the original exception to be able to go into the details.
Even so, if you can catch more concrete exceptions and provide better treatment for them you must do it.
If in a block of code you can get an SQLException and a NetworkException you must catch them and provide adequate messages and treatment for each of them.
But if at the end of the try/catch block you have an Exception mapping it to a BusinessException it's ok for me.
In fact, I find it adequate when higher service layers only throw business exceptions (with details inside).
Besides what yet answered by #anthares:
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
catch(Exception) is a bad practice because it catches all RuntimeException (unchecked exception) too.
This may be java specific:
Sometimes you will need to call methods that throw checked exceptions. If this is in your EJB / business logic layer you have 2 choices - catch them or re-throw them.
Catching specific exception classes means you will need to re-analyze your actions for which exceptions can be thrown when you look to see how this code handles exceptions. You will often get into a "what if..." situation and it can be a lot of effort just working out if exceptions are handled correctly.
Re-throwing means that code calling your EJBs will be littered with catching code that will typically not mean anything to the calling class. n.b. throwing checked exceptions from EJB methods will mean that you are responsible for manually rolling back any transactions.
But sometimes it is OK! Like if you have a piece of code that does something 'extra', which you really don't care about, and you don't want it to blow up your application. For example, I worked on a large application recently where our business partners wanted a certain daily transaction to be summarized in a new log file. They explained that the log wasn't all that important to them, and that it did not qualify as a requirement. It was just something extra that would help them make sense of the data being processed. They did not need it, because they could get the information elsewhere. So that is a rare case where it is perfectly fine to catch and swallow exceptions.
I also worked at a company where all Throwables were caught, and then rethrown inside a custom RuntimeException. I would not recommend this approach, but just pointing out that it is done.
Isn't it another valid scenario to ensure that a thread keeps alive catching exception inside it?
Thread shouldRunWhenApplicationRuns = new Thread() {
#Override
public void run() {
try {
// do something that should never end
} catch (Exception ex) {
// log it
}
};
shouldRunWhenApplicationRuns.start();
Sonar has also a good Explanation, why this is not a good idea, and how it can be prevented:
https://rules.sonarsource.com/java/RSPEC-2221
Catching Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.