Reputation: 377
I am not familiar with error/exception handling.
What is happening "under the hood" when an exception is caught
and thrown
?
I.e. what is the point of catching an exception in a try-catch block, then throwing it?
E.g:
try {
//Stuff
} catch(StuffException e) {
throw new MyException();
}
}
Upvotes: 6
Views: 1258
Reputation: 1065
Regarding the inner workings of the exception mechanism: There is plenty of documentation on this. I'm particularly a fan of this article: http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html
Ultra-short summary: When an exception is thrown, the jvm looks up in a table where the execution (of the init() method of the exception) continues.
For the second part of your question:
what is the point of catching an exception in a try-catch block, then throwing it?
I see some reasons for catching an exception an throwing another one:
You might want to catch an unchecked exception (because you know, "something bad might happen") and throw a checked one - so the caller has to handle it.
You want to use a custom Exception, maybe with additional information/logic
You're Implementing an error facade, e.g. throwing exceptions and catching them at the end in the facade.
Upvotes: 6
Reputation: 96385
Your example catches something with the type of StuffException, then throws a MyException. This is done to abstract away the original exception; it might be that the original exception is an implementation detail that the thing calling it doesn't need to know about (and which needs to be able to change, so that the caller shouldn't depend on it), and the exception thrown to replace it is part of the published API, which the caller can depend on. This is the case with Hibernate, it catches SQLExceptions generated in the course of calling JDBC functions, and wraps them in Hibernate exceptions, so calling code recognizes them as being thrown from Hibernate, and calling code doesn't depend directly on the JDBC exceptions, but on Hibernate's. If JDBC changed what exceptions it throws then, once Hibernate adapted to it, users of Hibernate wouldn't have to change.
What's bad about this example is that the stacktrace information for the original StuffException gets discarded when e goes out of scope, and MyException's stacktrace starts with the location that threw the MyException, making it difficult to find the source of the actual problem. Assigning the old exception to the new exception as its cause would preserve the original stacktrace information:
try {
//Stuff
} catch(StuffException e) {
MyException myException = new MyException();
myException.initCause(e);
throw myException;
}
}
Upvotes: 2
Reputation: 12440
Some possible uses of catching then throwing an exception:
handling more complex exception hierarchies
e.g. if you want to catch all IOException
s except for FileNotFoundException
(which is subtype of IOException
), you can do this:
try {
...
}
catch (FileNotFoundException e) {
throw e;
}
catch (IOException e) {
// handle exception
}
Upvotes: 0
Reputation: 4011
An exception is used to handle something that usually would not occur in the program flow. The point of throwing again an exception is that of changing the type of exception, as in your example. Doing that, you can create a custom exception and throw it inside another exception catch block.
EDIT
Here's an example:
Suppose you have a method which works with a Thread. Inside your method you have a delay:
Thread.sleep(3000);
but if you write just this, you will get an error because the sleep method is declared like this:
void java.lang.Thread.sleep(long millis) throws InterruptedException
So you will have to catch the exception:
try{
Thread.sleep(3000);
}catch(InterruptedException e){
//do stuff
}
Now, you don't like the InterruptedException and you want to handle it with your own custom exception. But how do you do that since the sleep method only throws that specific exception? The answer is this:
try{
Thread.sleep(3000);
}catch(InterruptedException e){
throw new CustomException();
}
At this point, if the InterruptedException is raised, it will be catched and it will be raised a CustomException instead.
Upvotes: 0