Unreacheable Catch Block Issue - java

Setup
So I have two exceptions:
ProfileException extends Exception
UserException extends Exception
One of my helper class method throws these two exceptions togeather:
Long getSomething() throes ProfileException, UserException
I invoke this method inside a try catch block like this.
try
{
Long result = helperObj.getSomething();
}
catch(ProfileException pEx)
{
//Handle profile exception
}
catch(UserException uEx)
{
//Handle user exception
}
Question
Now I NEED to necessarily distinguish between those two exceptions thrown by the method and handle the exceptions separately depending on the type of exception being thrown.
However I get the following error.
Unreachable catch block for UserException. It is already handled by the catch block for ProfileException.
How can I distinguish and handle seperately depending on the type of exception thrown by that getSomething() method?

This error indicates that UserException extends ProfileException

Since both exceptions are in the same level in the heirarchy, you have to use like following
try {
Long result = helperObj.getSomething();
}
catch(Exception ex) {
if (ex instanceOf ProfileException) {
//Handle profile exception
} else if (ex instanceOf UserException) {
// Handle user exception
}
}

I'm quite convinced that UserException probably extends ProfileException. If you modified it, it's probable that the IDE did not compiled the latest version (for instance because compiler errors occured). Therefore you can run a clean and build command (available in most popular IDEs).
You can simply resolve the problem by swapping the catch blocks:
try {
Long result = helperObj.getSomething();
} catch(UserException uEx) {
//Handle user exception
} catch(ProfileException pEx) {
//Handle profile exception
}
Most IDE's however will always write catch blocks from specific types toward more general types in order to prevent such dead code.

Related

How to throw an Exception inside a Try/Catch block?

I have the following Java method:
public Class createClass(Class class) {
try {
// retrieve the professor of the class and check if he exists
Professor professorFound = professorRepository.findById(class.getProfessorId());
if (professorFound != null) {
// if the professor exists, then check if he already has a class
// with the same id
List<Class> classes = professorFound.getClasses();
List<Class> classFound = classes.stream().... // loop to find the class...
// if he has, throw an exception
if(!classFound.isEmpty()) {
throw new ClassAlreadyRegisteredException();
} else {
// if he does not have, then create the class
Class class = new Class();
professorFound.getClasses().add(class);
return professorRepository.save(professorFound);
}
} else {
// if the professor does not exist, throw an exception
throw new ProfessorNotFoundException();
} catch (Exception e) {
// if there is any other error during the communication with the database,
// throw a generic IOException
throw new ClassIOException();
}
}
Basically, what I need is to throw specific Exceptions (if the professor informed in the request does not exist, or if the professor already has a class with the same id), or throw a generic IOException if there is any other error during the communication with the database.
However, in the way that I have developed, if any specific Exception is thrown, the try block will catch the exception and will throw a generic IOException.
How can I solve this problem?
I'm very interested in understanding what are the best practices in this case.
Should I catch each specific exception separately and throw them twice?
Is that a good practice?
EDIT:
This is how my ClassAlreadyRegisteredException looks like:
public class ClassAlreadyRegisteredException extends ApiException {
private static final long serialVersionUID = 1L;
public ClassAlreadyRegisteredException(String code, String message, String developerMessage, String origin, HttpStatus status) {
super(code,message,developerMessage,origin, status);
}
}
This is how my ApiException looks like:
#Data
#AllArgsConstructor
#RequiredArgsConstructor
#EqualsAndHashCode(callSuper = false)
public class ApiException extends RuntimeException{
private static final long serialVersionUID = 1L;
private String code;
private String userMessage;
private String developerMessage;
private String origin;
private HttpStatus status;
}
Thanks in advance.
Catch and re-throw.
try {
... same as before ...
} catch (ClassAlreadyRegisteredException | ProfessorNotFoundException e) {
throw e;
} catch (Exception e) {
// if there is any other error during the communication with the database,
// throw a generic IOException
throw new ClassIOException();
}
Alternatively, remember the exception to throw it later.
Exception fail = null;
try {
….
// save exception in place of existing throws
// for example:
fail = new ClassAlreadyRegisteredException();
…
} catch (Exception ex) {
...same as original...
}
if (fail != null) {
throw fail;
}
I use both techniques; the choice depends on what is simpler in any given situation. Neither is uncontestably better.
For the catch and re-throw method, you have to keep the list of caught-and-rethrown exceptions consistent with the exceptions you actually throw from within the try-clause. In larger cases, I'd avoid that problem by using an exception hierarchy, so I could catch the common base class.
For the save-and-throw method, you have to arrange control flow so that nothing significant is done after detecting the failure, since you don't have the immediate 'throw' command to exit the try-clause. Nevertheless there are cases where it is simple enough; the original example is one such.
Checked vs Unchecked Exceptions
It's totally acceptable to throw an exception in a catch block. A common use case is to take a checked Exception and throw a unchecked RuntimeException which would allow the exception bubble up to where it needs to be handled.
You'll want to use checked exceptions for use cases such as Connectivity/IO, SQL exceptions..
Handling Checked Exceptions
To answer your question, in most libraries that connect to the database, an checked IOException is thrown if there are any connectivity issues. For these cases, you can always specify this in the method signature public Class createClass() throws IOException
this specifies that any callers of createClass() has to fulfill the contract that the IOException is handled.
or
You can rethrow this as a RuntimeException
try {
...
} catch (IOException e) {
throw new RuntimeException(e); // <- send the original exception so you can preserve the exception and stacktrace.
}
This will essentially bubble up to STDOUT or whatever handler your framework specifies.
CAUTION:
However, catching an cover all Exception and throwing a more specific ClassIOException can have unintended consequences.
If you have a NullPointerException this will be captured by your catch (Exception e) block and rethrown as a ClassIOException
Doing this will corrupt the stacktrace and cause your error logs to be much more difficult to debug.
Understanding what constitutes an checked Exceptions.
Another tip is to consider what your Exception cases are.
If they are standard flow of the application, service, or business logic -- these may not be appropriate exceptions.
The ClassAlreadyRegisteredException and ProfessorNotFoundException may not be exceptional cases in your application... unless these are already specified by your professor.
Sometimes these can be thrown as RuntimeException if the situation calls for it.
Best Practices?
There are still many opinions on how exceptions are handled. So here are some rule of thumb questions I ask myself when working with exceptions
Is the stacktrace preserved? Will I be able to trace back to the root Exception
Is this common logic and represents an exceptional case that deviates from what my application provides?
If I throw this exception, is it an absolute necessity for anything calling this method to handle this exceptional logic?

Java Exception handle case

public void backendExecute(Map appParams, BackendTaskMetaData metaData) throws Throwable {
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (Exception e) {
LogServices.app.error("RPTPeriodicReportGenTask:"+ e.getMessage());
}
}
With regards to the method above, if object pointed to is null, would come across as NullPointerException, I want to know if this exception would be caught or thrown to the invoker method? thanks
Exception is a parent class of NullPointerException, so it will catch it and not throw it to the calling method.
As you are catching Exception class and NullPointerException is its subclass , exception will get catched not throwed.
Regard to above method, if object ptd is null, would come across nullpointexception,
Yes.
i want to know this exception would be catch or throw it to invoker method?
The exception would be caught by the handler. The handler will catch Exception and any exception that is descended from it. NullPointerException is a subclass of RuntimeException which is (in turn) a subclass of Exception. Therefore, it will be caught.
Now, if this may be just an illustrative example ... but it is a bad idea to:
declare a method as throws Throwable, or
catch Exception ... unless you are about to terminate the application.
Declaring a method as throwing Throwable makes it next to impossible for the caller to know what exceptions could be thrown. Instead, the compiler will insist that the caller catches ... or propagates Throwable.
Catching Exception has the problem that you will catch every subtype of Exception ... including various unchecked exceptions that 1) you are not expecting, and 2) are probably symptoms of bugs that you cannot safely recover from.
NullPointerException is a subclass of Exception and thus will be catched, however it is recommended that you don't try and catch runtime exceptions. It is better to avoid them.
For example a null pointer could be avoided by doing the following:
if(ptd != null) {
ptd.getBusinessKey();
} else {
//Notify the user in some way or do something else.
}
catch (Exception e)
means that this will catch any exception (i.e. any subclass of Exception) thrown inside the preceding try block - which, yes, includes NullPointerException. Note that this is generally considered a bad practice, as you almost always will want to handle different sorts of exceptions in different ways, hence the need for multiple catch statements.
For instance, consider a method that could potentially throw an IllegalAccessException at compile time or a NullPointerException at runtime - it's difficult to imagine a situation where you'd want to handle them the same way, so you'll typically want to do something like this:
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (NullPointerException e) {
//do something
} catch (IllegalAccessException e) { //for example...
//do something different
}

Idiom to let a specific exception bypass a broad catch block?

Often, when implementing a template method or interface method, you can only throw one specific type of exception defined by the method. But your implementation may make class to API's that throw an incompatible exception type, or many different exception types.
Naturally you need to catch them and wrap the exceptions into the type suitable for the implemented method signature. Lets assume we want to implement this interface:
public interface SomeDataGetter {
public long getSomeData() throws IOException;
}
Our implementation makes use of some other API product to implement this, and the API method we are calling may have this signature:
public long loadFromDBOrCache(Object ... params) throws SQLException, IOException, ObjectNotFoundException, RuntimeException, FridayException, NotWeekendException, NumberIs42Exception;
I made this up to demonstrate the case where you can't exactly enumerate all the possibly thrown exceptions by concrete type. Do note that IOException is a type we are allowed to throw from our implementation.
Now I can go the lazy route when implementing this and wrap anything to fit my signature:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
This will obviously wrap any exception into an IOException (even an IOException) and it works out ok. But I'd like to not wrap IOExceptions, since I am allowed to throw those without wrapping them:
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e.getMessage(), e);
}
}
You can imagine this gets cumbersome quickly if there are multiple possible exception in the implementation and multiple exceptions you are allowed from the implementation. I need an extra catch for each exception I want to pass throgh.
Whats the best idiom to keep that readable (also, I'm lazy, and don't want to write all these extra catches) and still avoid unneccessary exception nesting? Or shoud I not bother and just wrap everything?
One approach would be making a method that wraps all "prohibited" exceptions in an allowed one, while returning all the allowed ones unwrapped, like this:
private static void throwIoException(Exception e)
throws IOException // <<= Add other "allowed" exceptions here
{
if (e instanceof IOException) {
throw (IOException)e;
}
... // <<= Add checks for other "allowed" exceptions here
throw new IOException(e.getMessage(), e);
}
Now you can use a single catch block, and do the wrapping as needed:
try {
return loadFromDB(...);
} catch (Exception e) {
throwIoException(e);
}
One unpleasant consequence of this is that the stack trace shows the utility method at the top of the newly created IOException, but that's not important, because the real exception is the wrapped one, not the IOException wrapper. If the exception that you caught happens to be IOException, the correct stack trace should remain in place.
I would consider the lazy route of wrapping all exceptions you get into IOExceptions (or another checked exception) to be a bad practice. Instead I would consider wrapping the exceptions in runtime exceptions, thereby bypassing the catch or specify requirement. E.g.
#Override
public long getSomeData() throws IOException {
try {
return loadFromDB(...);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
The reason why this is better is that checked exceptions carry a certian meaning. If you catch for instance a ParseException in your code and rethrow that as a IOException you are lying. As a user of your code I might be able to do something about certain types of checked exceptions, but if you obfuscate the true cause of an exception it will be more difficult to debug the code when an error occurs.
In general I think you should minimize the use of checked exceptions since it litters error handling code throughout your application. Also if you are using someone else's code you have no guarantee that a RuntimeException won't be thrown anyway (unless you carefully read through it all). Therefore you have to consider that possibility anyway and handle it somewhere so your application don't crash. The virtues of unchecked exception vs checked exceptions has been discussed quite a lot elsewhere here and here for instance.

Is it possible to ignore an exception?

In Java, is it possible to make a method that has a throws statement to be not checked.
For example:
public class TestClass {
public static void throwAnException() throws Exception {
throw new Exception();
}
public static void makeNullPointer() {
Object o = null;
o.equals(0);//NullPointerException
}
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm forced to handle the exception, but I don't want to
}
}
You can try and do nothing about it:
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) { /* do nothing */ }
}
Bear in mind, in real life this is extemely ill-advised. That can hide an error and keep you searching for dogs a whole week while the problem was really a cat(ch). (Come on, put at least a System.err.println() there - Logging is the best practice here, as suggested by #BaileyS.)
Unchecked exceptions in Java extend the RuntimeException class. Throwing them will not demand a catch from their clients:
// notice there's no "throws RuntimeException" at the signature of this method
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ {
throw new RuntimeException();
}
Classes that extend RuntimeException won't require a throws declaration as well.
And a word from Oracle about it:
Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.
There are 3 things you can do :
Throw a RuntimeException (or something extending a RuntimeException, like NullPointerException, IllegalArgumentException,...), you don't have to catch these as they are unchecked exceptions.
Catch the exception and do nothing (not recommended) :
public static void exceptionTest() {
makeNullPointer(); //The compiler allows me not to check this
try {
throwAnException(); //I'm forced to handle the exception, but I don't want to
} catch (Exception e) {
// Do nothing
}
}
Change exceptionTest () declaration to say that it throws an Exception, and let the method calling it catch the Exception and do what is appropriate :
public static void exceptionTest() throws Exception {
makeNullPointer(); //The compiler allows me not to check this
throwAnException(); //I'm no more forced to handle the exception
}
In Java there is two kinds of Exceptions, Checked Exceptions and Unchecked Exceptions.
Exception is a checked exception, must caught or thrown.
NullPointerException is a RuntimeException, (the compiler doesn’t forces them to be declared in the throws claus) you can ignore it, ,but it still may occur in the Runtime, and your application will crash.
From Exception documentation:
The class Exception and any subclasses that are not also subclasses of
RuntimeException are checked exceptions. Checked exceptions need to be
declared in a method or constructor's throws clause if they can be
thrown by the execution of the method or constructor and propagate
outside the method or constructor boundary.
From the RuntimeException documentation:
RuntimeException is the superclass of those exceptions that can be
thrown during the normal operation of the Java Virtual Machine.
RuntimeException and its subclasses are unchecked exceptions.
Unchecked exceptions do not need to be declared in a method or
constructor's throws clause if they can be thrown by the execution of
the method or constructor and propagate outside the method or
constructor boundary.
No, it raises a compiler error. Being a checked exception, you must either catch it or propagate it by declaring your method as potentially throwing it.
Check this and this.
Throw a RuntimeException or an exception which is derived from RuntimeException. Then the compiler will not force you to catch it.
The other answers are right, in that they correctly tell you what you should do, but it is actually possible to throw a undeclared checked exception. There are a few ways this can be done; the simplest is:
public void methodThatSecretlyThrowsAnException() {
Thread.currentThread().stop(new Exception());
}
or if your goal is to wrap an existing method that does declare its exception
public void methodThatSecretlyThrowsAnException() {
try {
methodThatAdmitsItThrowsAnException();
} catch(final Exception e) {
Thread.currentThread().stop(e);
}
}
(Needless to say, you should never do this.)
Just catch an exception and dont do any thing with it, leave it as it is and catch the generic exception in case you are not aware of the specific exception
try{
//Your logic goes here
}
catch(Exception e)//Exception is generic
{
//do nothing
}
AS I know, it's impossible in the case. Only unchecked exception, compiler can skip to check. such as RuntimeException.
You can use a loophole in the Java Compiler. Add the following code:
public RuntimeException hideThrow(Throwable e) {
if (e == null)
throw new NullPointerException("e");
this.<RuntimeException>hideThrow0(e);
return null;
}
#SuppressWarnings("unchecked")
private <GenericThrowable extends Throwable> void hideThrow0(Throwable e) throws GenericThrowable {
throw (GenericThrowable) e;
}
You can catch the exception, then invoke hideThrow with the exception to throw it without the compiler noticing. This works because of type erasure. At compile time, GenericThrowable represents RuntimeException because that is what we are passing. At run time, GenericThrowable represents Throwable because that is the basic type in the type parameter specification.
It is not advisable to avoid an exception with an empty catch block even though you are completely sure that is not going to fail under any circumstance. Sometimes, we are not aware of the human factor.
If you are sure that an exception is very unlikely to happen (if not impossible) you should create your own Exception and and wrap the unexpected exception in it.
For example:
private class UnlikelyException extends RuntimeException {
public UnlikelyException (Exception e){
super (e);
}
}
Then wrap your code with a try-catch block and throw your exception, which you don't have to catch
try {
// Your code
} catch (Exception e) {
throw new UnlikelyException(e);
}

java: can't rethrow exception: Unhandled exception type Exception

I'd like to catch an exception, log it, set a flag, and the rethrow the same exception
I have this code:
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw ex;
}
return result;
}
But eclipse complains at throw ex, telling that "Unhandled exception type Exception", and suggests me to add a try-catch block around it.
In fact, I want the process calling this method to handle the exception, and not handle it myself... I just want to return true if everything goes ok, and log it if there's an exception
On the other hand, I can wrap the exception inside another exception, but I can't throw the same one..
any idea?
I think there are various things to mention here:
You either want doJobWithResult() to return true on success and false on failure, or return nothing on success and throw an exception on failure.
Both at the same time is not possible. In the first case, catch the Exception, log it and return false, in the second case change your signature to return void and throw an exception and handle it in the caller.
It's a Don't to catch an exception, log it and rethrow it. Why? Because a potential caller of your method does not know that you are already logging it, and migh log it as well.
Either throw an exception (in which case the caller has to deal with it) or catch it and handle it (log it).
Note that throwing Exception does not give the caller of your method any clue about what might potentially go wrong in your method, it's always better to throw more specific exceptions, or to wrap an exception in a user-defined one and rethrow it.
Moreover, if you throw Exception, a caller might be tempted to catch Exception without noticing that this will also catch every RuntimeException (since its derived from Exception), which might not be desired behavior.
Your doJobWithResult method needs to declare that it can throw Exception:
public Boolean doJobWithResult() {
becomes
public Boolean doJobWithResult() throws Exception {
You can throw the same exception if you add throws Exception to your method signature.
Otherwise you can throw a RuntimeException.
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
}
return result;
}
In such a case, you won't need to indicate that public Boolean doJobWithResult() throws something but make sure you handle it properly later on (catch or expect your thread to stop... it's a RuntimeException afterall).
Since Exception is checked, an alternative to catching the Exception is to declare your method as throwing it:
public Boolean doJobWithResult() throws Exception {
// ...
}
If doJobWithResult doesn't have to handle the exception, then remove the catch block and add "throws Exception" to the method signature. The exception logging can be done in the class/method that have to deal with the Exception in a corresponding try/catch block.
There is no need to set the result as false in the catch block, as the value won't be returned(as we are throwing an exception).
Your method should also declare that it throws an exception and so the client will be forced to handle it.
Also consider using a more specific exception which will be thrown in this particular case.
Add throws Exception to your method. You also don't need to add result = false; in your catch block.
I think the way you handle this exception is really appropriate if any failure of feed.fetchContents() method cannot be recovered. (Idea is better to halt rather than continuing)
Apart from that I would suggest you to use more specific exception hierarchy.
And another thing I got from effective java book is if you write such a method you must document with #throw (in comments) with the reason.
You could throw an unchecked exception
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
I spent the last hour looking for it since not even the Complete Reference book mentions this explicitly: unhandled throw ThrowableInstance works only with unchecked exceptions.. And only runtime exceptions are unchecked. By unhandled I mean something like this:
class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // re-throw the exception
}
}
public static void main(String args[]) {
try {
demoproc();
} catch(NullPointerException e) {
System.out.println("Recaught: " + e);
}
}
}
This example is taken verbatim from the Complete Reference book (9th edition).
The first throw statement i.e throw new NullPointerException("demo"); is handled by the following catch block, but the second throw statement i.e. throw e; is unhandled by the demoproc() method. Now this works here and the above code compiles successfully because NullPointerException is a runtime/ unchecked exception. If the e instance were a checked exception or even an Exception class instance then you'd get an error saying the exception e is unhandled and you'd either have to handle it within demoproc() or you'd have to explicitly declare that demoproc() throws an exception using throws in the method signature.

Categories