Does catching and rethrowing the exact same exception mean anything? - java

Lately, I have been seeing a lot of (commercial) code that throws and catches the exact same exception, similar to the code below:
public class Foo {
public void bar() throws AnException {
// do something (1)
try {
// do something (2) -- able to throw AnException
} catch (AnException ex) {
throw ex;
}
// do something (3)
}
}
Contrast this to:
public class Foo {
public void bar() throws AnException {
// do something (1)
// do something (2) -- able to throw AnException
// do something (3)
}
}
Does the former actually accomplish anything, in either behavior or semantics or else? Will it have any effect on code performance (time and space) or does it help readability?
P.S. this question is very different from this question.
EDIT: The catch block in the former doesn't do anything else other than rethrowing the caught exception.

This is a violation of a basic rule:
The code should catch only the exceptions that it knows how to handle.
Oracle's guidelines suggests that each time you throw an exception, you should supply something useful for the code that catches your exception (see page 3 of Effective Java Exceptions). Catching an exception simply to re-throw it serves no practical purpose, because there is no additional information added to it for the code above it in the invocation chain, and no information extracted by the method itself.

It makes no sense for sure assuming code you provided.
Rethrowing exceptions makes sense when you want to handle this exception somehow (e.g. log it) but want it to be handled further in a stack trace.
Regarding commercial code, maybe the reason you saw it was that there was some handling logic initially that was removed but exceptions rethrowing wasn't removed. I saw such situations several times.

There's no reason for the try/catch in the code you posted. As with #nickolay.laptev's answer, I believe that if you find this in commercial code, it's probably left over cruft from something that used to be meaningful.
Aside from some sort of partial error handling, there's another use case for simply catching and rethrowing an exception. This would be to prevent the exception from being caught by a subsequent, more general, catch clause. So, for instance, if you wanted to handle every exception other than instances of AnException, you would either have to do a type check:
try {
// stuff
} catch (Exception ex) {
if (ex instanceof AnException) {
throw ex; // rethrow since we're not handling it
} else {
// handle all other exceptions
}
}
or use something like this (which, in my view, is cleaner and more readable):
try {
// stuff
} catch (AnException) {
throw ex;
} catch (Exception ex) {
// handle all other exceptions
}
Then if you later decided to not handle all those other exceptions, you'd delete the second catch clause and end up with the code you posted.

Related

Is it acceptable to rethrow Exception's cause?

Sometimes I would want to throw an exception with more information to the user, so they can easily see why the method failed.
My method would look like this:
public myPublicMethod(...) throws Exception1, Exception2 {
try {
doSomething(); // this throws OtherException
}
catch (OtherException e) {
Exception cause = e.getCause()
if (cause instanceof Exception1) {
throw (Exception1) cause;
}
if (cause instanceof Exception2) {
throw (Exception2) cause;
}
throw new IllegalStateException("some other type of exception occurred", cause);
}
}
Is this design acceptable?
Your thinking is good, however in my humble opinion the way you implemented it is kind of missing the point, I'll try to explain.
You started with the claim that you want to give the user more information about the exception. What you did - striping the cause from its "parent exception" (e.getCause() and then throwing the cause) - actually gives the user less information, since the information in OtherException, that you discarded, might contain useful details about the flow caused the program to crash.
It is a good practice to catch the most specific exception and throw it to the caller, but make sure that you're not omitting details. Throwing the cause without the parent exception is actually omitting details.
It makes sense sometimes to wrap an exception that you caught and provide more details about it (like you intended to do in your last line), but again - make sure that you're only adding details, and not omitting details.
You can read more about exceptions handling best practices here.
I would want to throw an exception with more information
There's nothing wrong with the practice of catching an exception in order to provide additional information by wrapping it with a custom or built-in exception and re-throwing.
I think it's if you want to do it only for a limited number of types of exceptions by wrapping with the IllegalStateException and adding a custom message and preserving the cause of exception. But there's a caveat: a type of OtherException shouldn't be too broad, like general Exception, so that it will encompass only a limited number of exceptions types.
But re-throwing the only a cause like you've done for Exception1 or Exception2 looks suspicious. For some reason, you don't consider them to be the root-cases and going to blind on the information they could carry. It sounds like a design flaw. Also keep in mind that cause could be null (in this case, exception doesn't wrap anything) and this code will fail with NullPointerException. Therefore, in the in example below, the same exception will get re-thrown instead of re-throwing the cause.
From the clean-coding perspective, it's better to use as fewer type-checks as possible. And I think in this case you don't need to resort to instanceof check.
Instead, you can utilize the features that exception handling mechanism provides.
Since you need to perform the same action (re-throw the exception that was caught) if Exception1 or Exception2 occurs, if types Exception1 or Exception2 are siblings (i.e. they don't extend each other), these exceptions can be handled with a multi-catch clause to avoid code duplication:
catch (Exception1 | Exception2 e) {
throw e;
}
Otherwise, if let's say Exception2 is a subtype of Exception1 then you should handle them in the separate catch blocks starting from more specific type, i.e. subtype should be handled before supertype:
catch (Exception2 e) {
throw e;
}
catch(Exception1 e) {
throw e;
}
And after that add a catch clause with the least specific type (more wide than all exception types defined previously), to handle all other exception types that might take place by throwing a new instance of IllegalStateException.
Example:
public void myPublicMethod(Path source, Path destination)
throws FileAlreadyExistsException, DirectoryNotEmptyException {
try {
Files.copy(source, destination);
// do some other actions
}
catch (FileAlreadyExistsException | DirectoryNotEmptyException e) {
throw e;
}
catch (IOException e) {
throw new IllegalStateException("some other type of exception occurred", e);
}
}

Is it okay to declare a checked exception for an exception thrown by a called method?

Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException inside Do and declare Do like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException inside Do and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work.
Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch exceptions you're going to do something about.
Clean up code should be achieved with finally so the normal reasons to catch an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException.
In practice IllegalArgumentException and IllegalStateException should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen, then use try-catch, or you can just declare it on the method.
Beyond that, if EmptyThingyException is sub class of Exception, then it is no need to declare EmptyThingyException when you have declared Exception.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html.
**
Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read :
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices

How am I supposed to let an Unchecked Exception bubble up and log?

So quoting from this page, which is titled: Exception-Handling Antipatterns Blog and seems to be written (or at least to be approved) by Oracle..
An unchecked exception probably shouldn't be retried, and the correct response is usually to do nothing, and let it bubble up out of your method and through the execution stack. This is why it doesn't need to be declared in a throws clause. Eventually, at a high level of execution, the exception should probably be logged.
I am not sure if I understand this. How can I log an unchecked exception? If I have something like:
public static void main(String args) {
foo();
// How do I know what to log here? The method I am calling
// is not throwing an Exception.
// Do I just blindly catch(Exception ex)?
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
Can you help me understand what Oracle is suggesting here? I do not see any direct (or clear) way to catch runtime exceptions (I do not understand why it is not just called unchecked exceptions..) in higher levels and I am not sure how this suggested practice is useful. To me it would make more sense if it were talking about checked exceptions. Something like..
If a checked exception is thrown in a method that is not reasonable to be re-tried, the correct response is to let it bubble up and log..
You can also register a global ExceptionHandler that will handle the Exceptions that were not caught by your code:
Thread.setDefaultUncaughtExceptionHandler
This exception handle could then log whatever occured.
First of all, this is a general advice and it depends on the context. The idea behind it is that when a runtime exception occurs (ex. NullPointerException), the system is usually in an indeterministic state, meaning the rest of the code is not be guaranteed to execute as expected, so it's better to stop everything.
In most cases, your code will run in a separate thread and the exception will only stop the current thread, while the rest of the program keeps running.
This is not the case in your example, because everything is executed in a single thread, so the uncaught exception will effectively stop the whole program. In this scenario you might want to catch the exception and handle it.
public static void main(String args) {
try {
foo();
catch(Throwable t) {
t.printStackTrace(); // log exception
// handle the failure
}
}
You can also catch the exception earlier on, log and rethrow it further.
static void bar() {
try {
baz();
catch (Throwable t) { // catch
t.printStackTrace(); // log
throw t; // rethrow further
}
}
Edit: catch Throwable instead of Exception, will also catch Error
Note: Catching throwable is usually a bad idea, and should only be done with a specific purpose, not in general case. See #RC.'s comment.
As I understand it the documentation is suggesting that you have a generic handler at a high level of your code that logs such 'unexpected' (unrecoverable?) exceptions just as the comments in your main method suggest. So it might look something like this
public static void main(String args) {
try {
foo();
}
catch (ArithmeticException aex) { //if it's arithmetic log differently
log("arith issue! "+aex.getMessage());
}
catch (Exception ex) { //Otherwise do the best we can
log("unknown issue! "+ex.getMessage())
}
}
So there is still no path to recovery but at least before the process ends you get a chance to log the issue. You can also use the methods of Exception (or throwable) to get the stack trace and first causal exceptions in many case - so there is is a lot of extra useful information that might be logged.
There is a very straightforward way to catch unchecked exceptions, since they are all subclasses of RuntimeException or Error:
public static void main(String[] args) {
try {
// your code
} catch (RuntimeException | Error e) {
// handle uncaught exceptions, e.g.
e.printStackTrace();
}
}
How do I know what to log here? The method I am calling is not throwing an Exception.
As Joshua Bloch recommends in the Effective Java
Use the Javadoc #throws tag to document each unchecked exception that
a method can throw, but do not use the throws keyword to include
unchecked exceptions in the method declaration
And if you are using method wrapping in multilayered app i can recommend use exception translation:
Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction
See Effective Java item 61
So i think for your example actually you should use something like:
try {
bar();
} catch(NullPointerException e) {
throw new HigherLevelException(...);
}
The most important guideline regarding exceptions is that a method that couldn't sucessfully complete its task should throw an exception.
Only if you can guarantee successful completion of your method's task, you should catch an exception inside your method (without re-throwing this or another exception). From my experience that's only true in very specific situations, e.g. if you have an alternative way to try if some first attempt fails, or if you really really understand all possible causes of this specific Exception class that you are about to catch.
Speaking about RuntimeExceptions, there are so many different types of RuntimeException that you can hardly justify an assertion like "When such an exception arises in my code or a method called from inside my code, that won't affect the outcome of my method - I can continue just as if nothing happened." So, you should signal to your caller that you failed to fulfill your task, and the clearest way to do that is to let the exception ripple through, without try/catch block or throws declaration, just relying on Java's default behaviour.
In my opinion, the same reasoning applies to nearly all kinds of exceptions, not only RuntimeExceptions.
The difference with checked exceptions is that you have to declare them in the throws clause of your method. Then you have two choices: list the exception in the throws clause of your method (and all parent methods as well!) or catch the exception, wrap it in a new RuntimeException(ex), and throw that from your method.
With e.g. a typical GUI application, your users will be grateful if a problem in one menu function won't crash the whole application - probably other menu items might still work as expected. So, top-level commands or menu items are typically the places where to catch exceptions, tell the user something like "Oops!", log the exception to some file for later inspection, and allow the user to continue with another action.
In your main/foo/bar/baz application, I don't see a place where continuing after an exception makes sense. So the whole program should be aborted (which happens automatically in your case). If you want some error logging to a file, then establish an uncaught exception handler or wrap the body of main() in a try / catch(Throwable t) block. You'll probably want every exception logged, whatever type it is, so catch them all, and that's why I'm suggesting Throwable.
public static void main(String[] args) {
try {
foo();
}
catch(NullPointerException e){
System.out.println("NullPointerException in main.");
}
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
OUTPUT :
NullPointerException in main.
Basically the error is expected at a higher level, so there is no need to catch it on the baz() method level. If I understood correctly.
You can catch them just like any other exception with try-catch block. But the benefit is that you don't have to.
Use cases can vary. To my mind, the most popular is when it doesn't make sense to catch the exception right in that place or the appropriate handling should be implemented several levels (in terms of methods) higher than the method, calling the one throwing the exception (sorry, if that is not clear enough).
For example, the typical web application layout in java is as follows: you have a layer of controllers, a layer of services and a layer of dao. First one is responsible for dispatching requests, the second one is for managing business logic and the last one makes actual calls to db. So here for example it often doesn't make much sense to catch the exception in service layer if something goes wrong on the dao level. Here unchecked exceptions can be used. You log an exception and throw an unchecked exception so it could be handled some levels above for a user to get valuable feedback of work of the application.
If in this case you throw a checked exception you will have to rethrow it every level above just to bubble up it to the place of the actual handling. So here the unchecked exception is better to use in order not to copy and paste all that ugly try-catch block, rethrowing an exception and add the throws clause to the method.

Universal Catch Statement

I was wondering if there was a way to write a catch statement that is activated whenever any exception is thrown in a program. Thanks!
The problem with the answers you have received so far is that if you include a "catch-all" in your main, it will only catch exceptions thrown on the main thread.
A more robust way to catch all uncaught exceptions is to setup a DefaultUncaughtExceptionHandler for your project, for example, at the start of your main, you can call:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//log the exception
}
});
Note that it is generally unreasonable to do anything but logging in there, as the Throwable could be anything, including unrecoverable errors.
You can make the type Exception. That will catch any Exception, but it also doesn't give the programmer much information on what went wrong. It's usually better to try to be more specific about the type of exception that has occurred, mainly for semantic reasons.
The theory
Every type of Java Exception extends the Exception type. Because Exception is a superclass of all exceptions, when an exception is thrown, regardless of it's type, it can still be implicitly casted to an object of type Exception.
Edit
As mentioned in the comments, there is also type Error that can be thrown, so to really catch everything using the Throwable type is best. Throwable is more general than Exception, but it still works on the exact same principle. It is the superclass of anything that can be thrown.
For Example
try{
// Some code
}
catch(Throwable e)
{
// Do something. Edited due to comment!
}
To catch all exceptions some block of code may throw you can do: (This will also catch Exceptions you wrote yourself)
From How can I catch all the exceptions that will be thrown through reading and writing a file?
try {
// exceptional block of code ...
// ...
} catch (Exception e){
// Deal with e as you please.
//e may be any type of exception at all.
}
The reason that works is because Exception is the base class for all runtime exceptions. Thus any runtime exception that may get thrown is an Exception.
The is because all runtime exceptions inherit from Exception. Note that there is a difference between an Error and Exception Unchecked exceptions in Java: Inherit from Error or RuntimeException?, In that case you may need to do:
try {
} catch(Throwable e) {
}
See this When should Throwable be used instead of new Exception?. One user notes:
Error is programmatically unrecoverable in any way and is usually not to be caught, except for logging purposes (which passes it through again). Exception is programmatically recoverable. Its subclass RuntimeException indicates a programming error and is usually not to be catched as well. See comments for additional information.
Yes, any error that falls through will be caught by this:
try {
//do things here
} catch (Exception e) {
//handle exception here
}
Note, however, that it's typically the wrong thing to do.
In your main, put all your code in
try {
//Your code
} catch(Exception e) {
//Handle exceptions
}
This will handle any exception invoked by your code.

Writing catch block with cleanup operations in Java

I was not able to find any advice on catch blocks in Java that involve some cleanup operations which themselves could throw exceptions.
The classic example is that of stream.close() which we usually call in the finally clause and if that throws an exception, we either ignore it by calling it in a try-catch block or declare it to be rethrown.
But in general, how do I handle cases like:
public void doIt() throws ApiException { //ApiException is my "higher level" exception
try {
doLower();
} catch(Exception le) {
doCleanup(); //this throws exception too which I can't communicate to caller
throw new ApiException(le);
}
}
I could do:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
//ignore?
//log?
}
throw new ApiException(le); //I must throw le
}
But that means I will have to do some log analysis to understand why cleanup failed.
If I did:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
throw new ApiException(le1);
}
It results in losing the le that got me here in the catch block in the fist place.
What are some of the idioms people use here?
Declare the lower level exceptions in throws clause?
Ignore the exceptions during cleanup operation?
First, decide if you actually need to throw from the finally block - think carefully on that - in the case of a failed close() call... well, logging it is fine - but what can a higher layer of your API really do about the problem? So for 99% of the cases, you will log the secondary then re-throw the primary.
Next, if you do need to throw the secondary, decide if the various causes of the secondary exception are important. It will be rare that they are. So set the cause of the secondary to be the primary (either using an appropriate constructor, or initCause() ).
Finally, if you've must throw the secondary, and retain the full stack trace of the secondary and the primary - then you are in to creating a custom Exception to handle the situation. It's ugly, because you will probably want to derive from different parent classes. If this does arise, I suggest creating a helper class that is capable of filling the stack trace of a target exception in such a way that it produces a meaningful trace based on both exceptions (Be sure to use indentation for the secondary so nested exceptions are easy to pull apart).
But mostly, I suggest that you use the log-and-rethrow-primary paradigm. Focus on fixing the primary, and the secondary issues generally take care of themselves (the classic example here is an IO exception that munges things up so badly that the call to close() can't succeed either).
Use a finally block. If you are worried about swallowing the stack trace do the following:
Exception ex = new Exception(le.stackTrace());

Categories

Resources