Throwing or re-throwing an exception? - java

If I put in the catch clause:
...
catch(Exception e)
{
throw new Exception("msg", e);
}
Am I throwing or re-throwing the e exception?
So is correct to say that the throw clause used
into a catch is re-throwing an exception while using it
into a try block or elsewhere is throwing an exception?
Ultimately when or where thow throw an exception and when or where re-throw an exception?
Thanks.

You throw an exception the first time.
throw new Exception();
You re-throw a caught exception
} catch (Exception e) {
// do something
throw e;
}
You wrap an exception by throwing a different exception which contains that exception.
} catch (Exception e) {
// do something
throw new Exception(e);
}

I would call that throwing an exception.
This is re-throwing an exception:
...
catch(Exception e)
{
throw e;
}
I would throw a new exception if I want to wrap several exceptions into one, or if I want to add new information. If not, I think it's better to re-throw it.

To answer the last question:
Throw a new exception if doing so adds value. For example, it's common to wrap up underlying exceptions in application-specific exceptions for consumption in higher layers. These should almost always be chained to preserve the original exception's information.
IMO re-throwing is usually not a great idea, because a layer of context will be removed from the exception chain/stack trace. OTOH, if you genuinely can't do anything with it, re-throwing may make the most sense. In that case, I generally indicate the method throws and don't do local exception handling unless necessary for cleanup of local resources/etc.

If certain prerequisites are not met to execute a business condition we will throw custom exceptions, for example if balance in account is 0, can't debit, you will throw NotSufficientAmountException.
re-throw is for different purposes, one, to let caller know that something wrong happend, two, pass the stacktrace to caller with more details on which line of code error occured etc.,

http://www.codinghorror.com/blog/2004/07/rethrowing-exceptions.html
This link should help you make the decision of when to rethrow the exception.
Usually, the catch should be able to handle the exception itself, but if it cannot, then I'd advise re-throwing the exception. Another thing to take notice of is where the catch is (for example in a controller vs a model, you usually want the catch in a controller action so you can handle it in the view. However, exceptions happen in the model frequently)

Your question is: "Am I throwing or re-throwing the e exception?"
You are neither throwing or re-throwing the e exception
You are throwing a new Exception with some new message.
The original e exception (the exception that was caught) is the reason why you threw the new exception and consequently it will appear in the causedBy of the newly thrown exception.
oh boy.

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);
}
}

Declaring custom exception in Java

when I try to catch this exception it gives me a compilation error message that says, "exception LinkedListException is never thrown in body of corresponding try statement". What does this mean?
try {
LList.Node someNode = list.nextNode(node);
// We should not get here.
assertTrue(false);
}
catch ( LinkedListException ex) {
// If we get here we are happy as it throw the exception
}
The exception must be thrown somewhere in your code using throw keyword.
For example,
The ArithmeticException is thrown some where deep inside the code . If you don't want to handle( just like how the person thought about writing ArithmeticException) you can bubble up like
void someMethod () throws Exception
{
throw new Exception();
}
The person who called this method have to handle it with try,catch , finally like we usually do for exceptions IOException etc.
So, if you want to throw your exception, add this throw new LinkedListException() some where in your try block where ever you want to raise an exception.
If the exception is not a RuntimeException, then it must be declared (in the method signature throws clause). As such, the compiler can check if the code you call might throw this exception or not, and will not let you add a catch they will never be exercised.
If you are sure that this exception can be thrown somewhere deep down in that code, then it must have been caught and ignored or wrapped in another exception on the way. Or you are compiling against the wrong version of the class.

Need to throw checked exception in implementation, but it's not thrown by the interface?

I'm implementing the Accumulo BatchWriter interface to perform some additional computation over records before inserting. That computation may throw a checked exception if something goes wrong, but the only exception thrown by BatchWriter is the MutationsRejectedException. As such, I'm unable to throw the necessary checked exception when an error occurs in the pre-processing I'm trying to do.
Now, I could catch the checked exception and simply throw another exception in its place: either an unchecked exception like some RuntimeException or a MutationsRejectedException. Neither option seems great - an unchecked exception is a poor simulacrum of the exception I'd like to actually throw while throwing a MutationsRejectedException wouldn't allow me to see the actual cause of the error.
What is the best practice here?
"MutationsRejectedException wouldn't allow me to see the actual cause of the error."
Yes MutationsRejectedException would allow you to see the actual cause via chained exceptions.
Note the "Throwable cause" in the constructor.
Code for version 1.7;
try{
//...
} catch (Exception e) {
throw new MutationsRejectedException(null, null, (Map<TabletId,Set<SecurityErrorCode>>)null, null, 1, e);
}
.
try{
//...
} catch (MutationsRejectedException e) {
Throwable c = e.getCause();
if(c instanceof MyException){
//...
}else{
throw e;
}
}
The BatchWriter interface actually covers exactly your situation by expecting you to wrap whatever root cause you got into its MutationsRejectedException. That is much better design than declaring a general Exception and exception translation has been the recommended Java idiom since version 1.3 or so.
With throws Exception hopefully crossed out as an antipattern, all the choice you have is between exception translation and the "sneaky throw" idiom. I believe your preference would be the former, especially considering that the latter is very similar to having throws Exception, but more obscure.

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.

throwing exception inside the catch block

public void onClick() throws SQLException
try {
// Do something
} catch(MySQLIntegrityConstraintViolationException e) {
//Can i convert this exception to SQL Exception
}
Can i convert MySQLIntegrityConstraintViolationException to SQLException which is thrown by the method?
But the MySQLIntegrityConstraintViolationException already is a SQLExecption (through inheritence)! So there's no need to rethrow it (just remove the try/catch-block).
Sure you can wrap and rethrow - if you think it adds more information or makes your ideas more general. I think in this case the exception you're catching gives more info than the one you're thinking about.
I wouldn't choose a SQLException, though. It's a checked exception. I think the tide has turned from checked to unchecked exceptions.
Spring wraps SQLExceptions into unchecked DataAccessException that extends RuntimeException. I'd suggest that you follow suit.
Here's how you should do it:
catch(MySQLIntegrityConstraintViolationException e) {
throw new SQLException(e);
}
Don't just pass the message. Give the whole stack trace.
You can use the construtor of SQLException to create one in your Catch Block..
try {
} catch (MySQLIntegrityConstraintViolationException e) {
throw new SQLException(e);
}
Since MySQLIntegrityConstraintViolationException is subclass of SQLException re throwing is unnecessary. If you want to abstract your business logic layer from database specific details, make sure to catch SQL Exceptions in the logic layer so that even if the database is switched logic would still valid.

Categories

Resources