How to re-throw a Throwable? - java

Consider this code:
#Test(expected = NullPointerException.class)
public void testSaveEmptyApplication() {
try {
Application application = new Application();
Application result = applicationService.save(application);
} catch (Exception e) {
if(e instanceof UncheckedServiceException) {
throw e.getCause(); // java.lang.Throwable, compiler error
}
}
}
How to re-throw a Throwable?

The problem is that testSaveEmptyApplication is not declared to throw any checked exceptions. But e.getCause() returns Throwable which is a checked exception. So what you are doing in your example code is breaking Java's checked exception rules.
If you know that the cause really is a RuntimeException, then you can do this
throw (RuntimeException) e.getCause();
Caveats:
However, if your assumption is incorrect and the cause exception's actual class is a checked exception, the above will result in a (brand new) ClassCastException which squashes the cause exception you were trying to rethrow.
The above will also break if the cause was an Error, but you could deal with that; e.g something like this.
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new AssertionError("Unexpected exception class", cause);
}
If you want to be able to rethrow checked exceptions, then they must be declared in the method signature. Once you have done that you can discriminate and throw them as per the above pattern.
This is all a bit cumbersome. But this is the price you pay for having wrapped the exception in the first place.

One solution I can think of for there is:
The catch clause to be:
try {
// ...
} catch (Exception e) {
if(e instanceof UncheckedServiceException) {
if(e.getCause() instanceof NullPointerException) {
throw new NullPointerException(e.getCause().getMessage());
}
}
}
Otherwise change the method signature like this:
public void method() throws Throwable {
// ...
}

Related

Custom Exception that wraps Multiple Exceptions : Encouraged or Not?

I am coding a Java Library that will be used to access a DB.
I am throwing the exceptions to the end-programmer who uses the JAR library to handle it the way he/she wants.
I wrote a custom Exception (provided below) to wrap connection specific exceptions together so the end-programmer will not have to catch all these exceptions in his code. (to make it easy for him)
is this a good practice when it comes to coding Java libraries?
By using this the user will only have to catch NConnectionException in his code.
public class NConnectionException extends Exception {
private static final Logger logger = LoggerFactory.getLogger(NConnectionException.class);
public NConnectionException(Exception e) {
if (e instanceof NullPointerException) {
logger.error("ERROR IN READING DF");
e.printStackTrace();
}
else if (e instanceof FileNotFoundException) {
logger.error("FILE NOT FOUND");
e.printStackTrace();
} else if (e instanceof ParserConfigurationException)
{
logger.error("PARSE CONF ERR");
e.printStackTrace();
}
else if (e instanceof org.xml.sax.SAXException)
{
logger.error("SAX ERR");
e.printStackTrace();
}
else if (e instanceof IOException)
{
logger.error("IO ERR");
e.printStackTrace();
}
}
}
You can pass a cause (Throwable) to a custom exception. Look at the Exception javadoc for more Information.
Edit:
public class CustomException extends Exception {
public CustomException(Throwable t) {
super(t);
}
}
public void testMethod(String s) throws CustomException {
try {
int integer = Integer.parseInt(s);
} catch (NumberFormatException e) {
throw new CustomException(e);
}
}
try {
testMethod("not a number");
} catch (CustomException ce) {
ce.printStackTrace(); // this will print that a CustomException
// with the cause NumberFormatException has occured.
ce.getCause(); // this will return the cause that
// we set in the catch clause in the method testMethod
}
According to this post, wrapping all the exceptions in a single is not good.
If you want to wrap them then
As your program will throw only one exception at a time then no need to store list of exceptions in NConnectionException.
And you can create a single object of exception in NConnectionException class. You can refer this structure.
And store the thrown exception in that object and throw back newly created object of NConnectionException class. Let the calling program catch NConnectionException exception and take out the stored object and act accordingly.
Note : Generally we don't handle unchecked exception (like NullPointerException), calling program will take care of it.

Custom Exception that throws only specific Exceptions

I have a method which will throw SecurityException,NoSuchFieldException, IllegalArgumentException, IllegalAccessException.
I want to Custom Exception clause so that it will throw only the above Exception.
If any other exception comes, my Custom Exception clause should not throw it.
Is there a way or two to do this?
Thanks.
May be you can test the type of exception, for example:
if (e instanceof SecurityException) {
// do sth;
} else if (e instanceof NoSuchFieldException) {
// do sth;
} else if (e instanceof IllegalArgumentException) {
// do sth;
}

propagating error upwards in java

I have a main class where I have something like
void FooBar(String s){
try {
parseString(s);
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
context.getCounter(Counters.ERROR).increment(1); // this increment doesnt increases
}
}
parseString is
void ParseString(String s){
if (matcher.matches()) {
} else {
//throw exception
try {
throw new Exception("bad formatted N-triples");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
But for some reason, the error is not propagated upwards. In my FooBar method the error counters are not incremented even if the function gets bad formatted data.
How do I propagate this exception upwards?
But for some reason, the error is not propagated upwards...
The reason it is not propagated upwards is that you caught it. Exceptions stop propagating when they are caught.
Either don't catch it in parseString, or rethrow it in the handler; e.g. e.printStackTrace(); throw e;
However, this is likely to get you into more problems, specifically because of the exception you are catching / throwing here. The problem is that Exception is the root of all checked exceptions:
Since it is a checked exception, the method parseString must declare that it throws the Exception if you want to the exception to propagate.
But throws Exception is saying that this method could throw any possible checked exception ... which makes life difficult for the caller. (Not in this example ... but in general.)
My advice is as follows:
Avoid creating / throwing Exception. Pick a more specific (checked or unchecked) exception that reflects the meaning of the "exceptional event" you are trying to report ... or implement your own exception class. In this case throwing IllegalArgumentException would probably be better, though that is an unchecked exception.
Avoid situations where you need to propagate Exception.
Be careful when you catch Exception. It catches every (non-Error) exception, including all of the unchecked ones; i.e. RuntimeExecption and its subclasses.
You either don't catch it in ParseString, or you rethrow it with throw e;
Once an exception is caught, it doesn't get propagated unless you throw it again.
Examine what you're doing here:
try {
throw new Exception("bad formatted N-triples");//You throw an exception!
} catch (Exception e) {//And immediately catch it!
e.printStackTrace();
}
Because the exception is caught, it will not propagate. Instead, remove the try/catch block and simply throw the exception:
void ParseString(String s){
if (matcher.matches()) {
//code for reasons
} else {
//throw exception
throw new Exception("bad formatted N-triples");
}
}
Note that this is actually bad practice. You want to say something about your exception, and declare it:
void ParseString(String s) throws IllegalArgumentException {
if (matcher.matches()) {
//code for reasons
} else {
//throw exception
throw new IllegalArgumentException("bad formatted N-triples");
}
}
The surrounding function should know how to cope with that exception explicitly, rather than just throwing it's hands up because it's a general exception.
You shouldn't surround your error with try/catch:
void ParseString(String s){
if (matcher.matches()) {
}
else{
//throw exception
throw new Exception("bad formatted N-triples");}
}
}
When you throw the error, it's caught in the catch statement within parseString method, which is why isn't isn't propagated to the top.
Ideally, you'd do:
void ParseString(String s) throws Exception {
if (matcher.matches()) {
}
else{
//throw exception
throw new Exception("bad formatted N-triples");}
}
}

Handling Runtime exception in Java

I have the following piece of code
try{//do something
}
catch (Exception e) {
log.error(e, e);
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
the findbugs stataic analysis tool throws this warning on it
instanceof will always return true for all nonnull values in methodX, since all RuntimeException are instances of RuntimeException
what i dont understand is that its Exception which is being caught and not the RuntimeException, so why this warning ?
Perhaps, the // do something code does not throw any checked exception, so the only exceptions you can get in your try-block are unchecked ones (subclassing RuntimeException).
You could also try following code. This will be better to read and maintain.
try{//do something
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
Probably there is no methods that throws not RuntimeException in "try" part. Therefore, you can use construction
catch(RuntimeException e)
{
//Do something
}
Try http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Throwables.html#propagate%28java.lang.Throwable%29. It does exactly what you want. Today I did the replacement for the same reason (findbugs warning), also looked the source of this method.

Magic Exception thrower without declaring throws Exception

I want a method that can throw any Throwable including sub classes of Exception. Ive got something that takes an exception, stashes it in a thread local, then invokes a class.newInstance. That class ctor declares that it throws Exception then takes the threadlocal and throws it. Problem is it does not work for the two declared Exceptions thrown by Class.newInstance() namely IllegalAccessException and InstantiationException.
Im guessing any other method using some sun.* class is just a hack and not really reliable.
Wrapping is not an option because that means catchers are catching a diff type and that's just too simple and boring...
static public void impossibleThrow(final Throwable throwable) {
Null.not(throwable, "throwable");
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
try {
THROW.set((Exception) throwable);
THROWER.newInstance();
} catch (final InstantiationException screwed) {
throw new Error(screwed);
} catch (final IllegalAccessException screwed) {
throw new Error(screwed);
} finally {
THROW.remove();
}
}
private final static Class<Impossible> THROWER = Impossible.class;
private final static ThreadLocal<Exception> THROW = new ThreadLocal<Exception>();
static private class Impossible {
#SuppressWarnings("unused")
public Impossible() throws Exception {
throw THROW.get();
}
}
From Java Puzzlers (puzzle 43):
public static void impossibleThrow(Throwable t)
{
Thread.currentThread().stop(t); // Deprecated method.
}
The book shows other methods of achieving the same problem, one is a simplified version of yours, the other exploits generic type erasure to throw any Throwable where an Error is expected.
If you want an Exception to bubble up through code not expecting that exception then just wrap it in a RuntimeException
} catch (RuntimeException e) {
throw e; // only wrap if needed
} catch (Exception e) {
throw new RuntimeException("FOO went wrong", e);
}
Remember to let the message be informative. Some day you will have to fix a bug based only on the information in the stack trace.
Wrapping an exception inside a RuntimeException (as suggested by Thorbjørn) is the way to go. However, you usually want to maintain the stacktrace of the original excpetion. Here's how:
public static void rethrow(final Throwable t)
{
if(t instanceof RuntimeException)
throw (RuntimeException) t;
RuntimeException e = new RuntimeException(t);
e.setStackTrace(t.getStackTrace());
throw e;
}
I patched javac to remove the error, compiled impossibleThrow(), renamed the source file to something that does not end in .java (which forces the next compile to use the existing .class) and used that.
There is some validity for this question as a debugging tool. Suppose you are working with some code that may have failed and you see that it (perhaps) catches certain exceptions and (perhaps) throws certain exceptions. You suspect that an unexpected exception was not caught. However, the underlying code/system is too complex and the bug is too intermittent to allow you to step through in the debugger. It can be usefull to add the throwing of an exception without changing the method in any other way. In this case, wrapping the exception with a RuntimeException would not work, because you want the calling methods to behave normally.

Categories

Resources