In java there is a possibility of re-throwing the exception but there is any advantage in it?
One example of when you want to rethrow an exception is when you don't really know how to handle it yourself, but you'd like to log that the exception was thrown. Rethrowing it allows you to both capture the stack information that you need to log, and pass the exception up the call stack for the caller to handle.
Sure. If you need to perform some special processing (logging, clean up, etc) for the exception, but can't "handle" it completely, it is common to do the processing and then rethrow the exception. Note, that in many cases (especially cleaning up resources) you probably want a finally clause rather than a catch/rethrow.
Sometimes, you want a specific type of Exception to be thrown by a method, but there are rare instances that cause other Exceptions to be thrown within the method. I often wrap the causal Exception with my desired Exception and then rethrow the desired Exception.
This is really useful when you can't determine that the Exception has caused your operation to fail until control is passed to the calling method (or one of its ancestors), since if the process does eventually fail, I can trace back in the stacktrace to see why.
I haven't done Java in years, but from what I remember it's just like other languages with exceptions and OO. Exceptions can be subclassed, and often, you'll want to catch a base class of many exceptions, but might not be able to handle all of them. So say you're handling a remote file transfer, and want to catch all IOErrors, because you handle most of them, but not DiskFull. You can rethrow that, and let someone else deal with it further up the chain, but deal with the other issues, like TransmissionFailed, by re-doing the transmit.
If you can somehow justify that you need to re-throw the same exception that you caught, I'd argue that there is something wrong with your design.
Catching one exception and re-throwing another makes perfect sense. For instance, you may want to add detailed information that the original exception did not have.
Real World Cases
Here are some real world situations in which I needed to rethrow java exceptions:
When doing JDBC call, I would catch a SQLException. However, postgres would throw a PSQLException with additional data and status. In testing edge cases we were able to corrupt the database and we wanted the logger to have very specific data on the exception and state. We would wrap the original exception in a new exception with more data regarding the server state and rethrow.
When implementing a text parser, I would want to catch a number of runtime parsing exceptions such as NumberFormatException and pass them up the stack with additional data on what text caused and the source of the text that caused the parsing exception.
My coworker told me of a project in which he worked where every exception was wrapped in another exception of one of two types - RetryableException and FatalException. In the case of a Retryable exception, the application would wait and retry the operation after a fixed period of time. I'm not exactly sure about how I feel about this design, but I can see it as a stop-gap for dealing with some transactional issues.
In some cases I would be using an existing API that had a throws defined for a high-level exception and I would be doing an operation that would throw an unrelated exception (that I felt really belonged as a RuntimeException) - I then would rethrow the exception as the cause of the more general exception.
The most pure case that I can think of in which you may want to rethrow an exception is when you want to add additional data to it. For example:
public bizMethod() throws CoolBizLogicException {
int policyId = getPolicyId("bar");
try {
coolBizLogic(foobar); // this throws an exception
}
catch (CoolBizLogicException cble) {
cble.setPolicyId(policyId);
throw cble;
}
}
I don't think so. If you can't handle it, don't catch it.
Related
One of the projects I inherited is riddled with tons of try/catch blocks catching the general Exception. I've been slowly but surely refactoring this, but there are so many, such that I have been contemplating bringing this up as a concern in a meeting. This got me to thinking...Is there ever really a case where catching the general exception is justified in a production environment? I could not think of a case where I NEEDED to catch the general exception, but I'm also a fairly recent grad and I'm sure there's tons that I don't know. I did a little research, and I can find lot's of reasons why NOT to catch the general exception, but nothing concrete on when this practice is justified. Obviously if you're calling a method that already throws Exception you have to catch it. But is there ever a reason some method could throw Exception and it should not be refactored to throw the specific exception.?
Throw Exception only if you need to throw Exception, specifically. If you throw too-general an exception, you are effectively just shouting "there is a problem", without giving specific information as to what that problem is.
Catch Exception only if Exception is thrown, specifically. If you catch too general an exception, you're losing the opportunity to handle specific exceptions in the correct way.
Throwing Exception is the equivalent of returning Object instead of a more-specific type which would be useful to the caller; catching Exception is the equivalent of assigning a return value to an Object variable, rather than a more specific type that you could do useful things with. Basically: you are discarding available type information.
Sometimes you have to throw Exception, because you are writing a general framework. For example, Callable.call throws Exception, because you don't know what code will be executed there, so allowing it to throw Exception means that you don't constrain users of the class. And consequently, if you're calling a Callable, you need to catch Exception; but you need to do it with care.
The vast majority of people aren't (or shouldn't be) writing frameworks, and so you shouldn't be throwing or catching Exception.
There is good advice on this in Effective Java, Item 61, " Throw exceptions appropriate to the abstraction" (this is the number in 2nd Ed; don't know about 3rd Ed). Basically: you almost certainly don't want to throw Exception, but you might want to throw IOException rather than FileNotFoundException, if the fact that you're reading from a file isn't relevant to your API.
Catching general Exception isn't best practice, because if you are catching exception you are telling that you can handle it and recover from that exception state, but if you can't recover then it might be better to fail than to keep working with very unpredictable state.
Another thing that can happen is to catch exception that is supposed to be handled at higher level which can again lead to dangerous state.
There is possibility that code was written before Java 7 when multi-catch was introduced so they used Exception instead of writing each separately, or that developer wasn't familiar with this.
Only case in which catching Exception is justified, in my opinion at least, is at top of the application(main) - catch all exceptions that are not handled at lower levels, log them and exit for safety reasons, and crash nicely and show reasonable message to end user.
This brings us to another thing, and that is throwing Exception, same as with catching one you shouldn't throw Exception, that is same like returning Object from every method, you lose identity.
If this two things are very common in project you are working on maybe you should consider mentioning that to senior developer.
I'm trying to understand difference between error and exception but it looks same thing and on Oracle Official tutorials I read this line.
Checked exceptions are subject to the Catch or Specify Requirement.
All exceptions are checked exceptions, except for those indicated by
Error, RuntimeException, and their subclasses.
Now about I'm thinking it's same. But after searching more I found some difference as theoretical that.
Exception: are recoverable
Errors: not recoverable.
Exception Example:
try{
read file
}
catch(FileNotFoundException e){
// how I can recover here? can i create that file?
// I think we can just make log file to continue or exit.
}
Error Example:
try{
try to locate memory
}
catch(MemoryError e){
// I think we can just make log file to continue or exit.
}
Edited
I'm asking about recover-able and non-recoverable.
Error, as you already figured out, means you are in serious trouble. In a catch block you might be able to do something like logging, but basically that's it.
Non-recoverable exceptions are mostly runtime exceptions like NullPointerException. They are usually the result of some missed checks in the program code. Therefore the solution is normally to fix the code.
A recoverable exception is something that you know beforehand can happen and take certain measures. Think of a web application that calls some backend service. That service may or may not be available which can cause the execution of the operation to fail. Therefore you have a checked exception, in this case most likely a custom exception that you throw, and then handle it in the front end code in a manner where you tell the user, sorry backend service xy is down, try again later or contact support.
Recoverable does not mean that the application can do something to resolve the cause of the exception, though there may be cases where this is possible.
All classes that inherit from class Exception but not directly or indirectly from class RuntimeException are considered to be checked exceptions.Such exceptions are typically caused by conditions that are not under the control of the program.
Example
in file processing, the program can’t open a file if it does not
exist.
Recoverable
So It is very easy to know that if a file does not exists so you dont need to open that file hence that is recoverable
All exception types that are direct or indirect subclasses of RuntimeException (package java.lang) are unchecked exceptions. These are typically caused by defects in program’s code.
Example
ArrayIndexOutOfBoundsExceptions
ArithmeticExceptions
Error
Unrecoverable
So thatswhy program can not recover from these kind of errors or exceptions
Unrecoverable errors are the ones that put the application in an undefined state, like a broken database connection or a closed port, you may handle the error and continue to execute but it would not make sense. Modern languages like Rust and Go use the name panic for errors of these nature, to make the distinction clear. Best action to take is logging the error, if it is possible, and exiting the application.
A recoverable errors are the ones we can handle gracefully, like division by zero or validation errors. It is something expected and the resulting behavior is covered in the language spec. Yes, application behaves erratic when that a recoverable error happens but we can contain it or work around it.
The Object Throwable has 2 childs : Exception and Error.
All Exceptions are recoverable and all Errors are non-recoverable.
All Exceptions are recoverable because you can catch them and let your program continue its execution.
However all Errors , even when you add them to a catch block, will cause the abrupt termination of your program.
Examples of Errors: StackOverflowError, OutOfMemoryError,..
Remark : Checked and unchecked Exceptions are childs of Exception so recoverable.
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
Are there any guidelines on exception propagation in Java?
When do you add an exception to the method signature?
For example: if an exception is only thrown when an essential program resource is missing, and can only be handled at the top level, do I propagate it through all methods using this exception through all the methods using the erring method?
Are there any good practices? Any bad practices?
I'm sorry if I'm being vague, but I'm just looking for some (general) advice on programming style concerning exceptions.
Guidelines that have helped me in the past include:
Throw exceptions when the method cannot handle the exception, and more importantly, should be handled by the caller. A good example of this happens to present in the Servlet API - doGet() and doPost() throw ServletException or IOException in certain circumstances where the request could not be read correctly. Neither of these methods are in a position to handle the exception, but the container is (which results in the 50x error page in most cases).
Bubble the exception if the method cannot handle it. This is a corollary of the above, but applicable to methods that must catch the exception. If the caught exception cannot be handled correctly by the method, then it is preferable to bubble it.
Throw the exception right away. This might sound vague, but if an exception scenario is encountered, then it is a good practice to throw an exception indicating the original point of failure, instead of attempting to handle the failure via error codes, until a point deemed suitable for throwing the exception. In other words, attempt to minimize mixing exception handling with error handling.
Either log the exception or bubble it, but don't do both. Logging an exception often indicates that the exception stack has been completely unwound, indicating that no further bubbling of the exception has occurred. Hence, it is not recommended to do both at the same time, as it often leads to a frustrating experience in debugging.
Use subclasses of java.lang.Exception (checked exceptions), when you except the caller to handle the exception. This results in the compiler throwing an error message if the caller does not handle the exception. Beware though, this usually results in developers "swallowing" exceptions in code.
Use subclasses of java.lang.RuntimeException (unchecked exceptions) to signal programming errors. The exception classes that are recommended here include IllegalStateException, IllegalArgumentException, UnsupportedOperationException etc. Again, one must be careful about using exception classes like NullPointerException (almost always a bad practice to throw one).
Use exception class hierarchies for communicating information about exceptions across various tiers. By implementing a hierarchy, you could generalize the exception handling behavior in the caller. For example, you could use a root exception like DomainException which has several subclasses like InvalidCustomerException, InvalidProductException etc. The caveat here is that your exception hierarchy can explode very quickly if you represent each separate exceptional scenario as a separate exception.
Avoid catching exceptions you cannot handle. Pretty obvious, but a lot of developers attempt to catch java.lang.Exception or java.lang.Throwable. Since all subclassed exceptions can be caught, the runtime behavior of the application can often be vague when "global" exception classes are caught. After all, one wouldn't want to catch OutOfMemoryError - how should one handle such an exception?
Wrap exceptions with care. Rethrowing an exception resets the exception stack. Unless the original cause has been provided to the new exception object, it is lost forever. In order to preserve the exception stack, one will have to provide the original exception object to the new exception's constructor.
Convert checked exceptions into unchecked ones only when required. When wrapping an exception, it is possible to wrap a checked exception and throw an unchecked one. This is useful in certain cases, especially when the intention is to abort the currently executing thread. However, in other scenarios this can cause a bit of pain, for the compiler checks are not performed. Therefore, adapting a checked exception as an unchecked one is not meant to be done blindly.
You should handle the method as soon as possible, but it must make sense. If the exception doesn't make sense to be thrown by your method, but you can't handle it, wrap it into another exception and throw this new exception.
A bad practice about exception is to catch them all (it's not pokemon, it's java !) so avoid catch(Exception e) or worse catch(Throwable t).
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.