Handling recoverable and unrecoverable exceptions - java

Hopefully I can explain this clearly. If I have a main method with lots of steps that can generate different exceptions, some fatal, some not, do I have to catch the "recoverable" ones separately? It seems like that would result in potentially a lot of try/catch blocks, like so:
public static void main (String[] args) {
try {
//...
for (int i=0;someArray.length;i++) {
try{
System.out.println("I = " + i);
doSometing(i);
} catch (RecoverableException e) {
//recover, continue, whatever
//log warning
//keep
}
}//end for loop
try {
doSomethingElse();
} catch (AnotherRecoverableException e) {
//not fatal, keep on chugging
}
//...
//do more stuff that can throw unrecoverable exceptions
} catch (UnrecoverableException e) {
System.out.println("I can't handle this, it's too much!");
e.printStackTrace();
}
}
Is there a better way to do this?

My patterns are to let exceptions propagate when they would represent programming bugs and handle them as closely to the "problem" when you can handle them.
The problem is that many potential Programming bugs throw checked exceptions which is really bad (Checked exceptions are kind of a failed experement, the newer languages have gotten rid of them).
So:
Handle checked and unchecked exceptions that you can deal with immediately.
If you don't know how to handle a checked exception rethrow it as an unchecked exception.
any "top level" loop like in main or a thread should be surrounded by a try/catch/log of "Exception" to ensure that any exception that bubbles up doesn't kill the thread (but log it loudly because it represents an unknown programming bug!)
Any critical loop that should continue regardless of exceptions should have a try/catch/log of "Exception" inside the loop construct so it will continue.
Catch exception, not throwable at this high level. Throwable includes unrecoverable exceptions that you probably never want to catch.
If you really must throw an exception you think you want the caller to catch (try to avoid this--It means you are using Exceptions as code flow!), throw an unchecked exception but document it and have the method "throw" the unchecked exception (it doesn't HAVE to be handled, but this acts as additional documentation/hint).
Just as a background for why I dislike checked exceptions so--it makes code like this happeen:
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
This can hide some INCREDABLY annoying to find program-flow related bugs. In this case it simply means you might have some thread-control issues, but in others it can mean your code-flow "Magically" vanishes mid-method with no indication whatsoever (because an exception was picked up by a higher level try/catch).

If you are using Java 7 then you can club exceptions in the catch block using pipe as separator. This will reduce your number of catch blocks. But you need to decide how you want to handle them by putting appropriate code in the catch block.
In Java 7, you can do this:
try
{
...
}
catch(Exception1 | Exception2 | Exception3 e)
{
//Handle
}
catch(Exception4 | Exception5 | Exception6 e)
{
//Handle differently
}

You can use. defaultUncaughtExceptionHandler, but it only triggers if the Thread doesn't have a uncaughtExceptionHandler set.

For java versions other than 7, a cleaner approach is to handle exceptions in called methods. This makes code readable as shown below:
doSomething(int i){
//code
try{
//code
}catch(Exception1 e1){
//handle
}
catch(Exception2 e2){
//handle
}
}
doSomethingElse(){
//code
try{
}catch(Exception1 e1){
//handle
}
catch(Exception2 e2){
//handle
}
}
public static void main (String[] args) {
for (int i=0;someArray.length;i++) {
doSometing(i);
}//end for loop
doSomethingElse();
}
I do not recommend using generic Exception to catch all errors in one block. This makes difficult to know specific exceptions and prevents specific handling of them.

Related

Fatal exception handling in Java

I am creating a basic math parser with Java and doing this is revealing my shallow understanding of Java exception handling.
when I have this input:
String mathExpression = "(3+5";
and I subsequently call:
throw new MissingRightParenException();
the IDE forces me to surround with a try/catch like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
however, in order to force this to be a fatal exception, it looks like I have to add my own code to call System.exit(), like so:
try {
throw new MissingRightParenException();
} catch (MissingRightParenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
I am not sure I understand the syntax behind all of this, especially why I have to use a try/catch block around throwing an exception.
what is the rhyme and reason behind this?
Instead of throwing the exception, I could do this instead:
new MissingRightParenException();
instead of calling
throw new MissingRightParenException();
so I guess my question is - if this is a fatal exception, what is the best way to make it truly fatal while giving the user the best feedback?
If you want to have a checked exception that you have to catch - but not right away - then you can define throws MissingRightParenException in the signature of your methods.
class MissingRightParenException extends CalculationException {
...
}
class CalculationException extends Exception {
...
}
class MyClass {
int myMathRelatedMethod(String calculation) throws CalculationException {
...
if (somethingWrong) {
throw new MissingRightParenException("Missing right paren for left paren at location: " + location);
}
...
}
public static void main(String ... args) {
...
try {
myMathRelatedMethod(args[0]);
} catch (CalculationException e) {
// stack trace not needed maybe
System.err.println(e.getMessage());
}
...
}
}
You can also define it as the cause of a RuntimeException but that doesn't seem a good match for your current problem.
try {
...
throw new MissingRightParenException();
...
} catch (MissingRightParenException e) {
// IllegalStateException extends (IS_A) RuntimeException
throw new IllegalStateException("This should never happen", e);
}
If your MissingRightParenException class extends RuntimeException then you don't have to catch it. The message will fall through all methods where it (or it's parent classes such as Throwable, Exception and RuntimeException) is not explicitly caught. You should however not use RuntimeExceptions for input related errors.
Usually the user will get the stack trace or at least the error message, although that depends of course or the error handling further down the line. Note that even main does not have to handle exceptions. You can just specify throws Exception for the main method to let the console receive the stack traces.
So in the end: use throws in the signature of your methods instead of catching exceptions before you want to handle them.
Assuming that your exception is currently a subclass of Exception, which is a Checked Exception, you need to handle in a try catch. If you can make your exception a RunTimeException, you no longer need to do the try-catch stuffs.
what is the best way to make it truly fatal while giving the user the
best feedback?
Personally, I don't think a missing parenthesis should be a Fatal exception. The user should have the possibility to re-try.
However, if you really want to know, It is not possible with java to create a custom fatal exception as fatal exception means something went wrong on the system/jvm, not on the program itself. Still, you should change System.exit(0) to System.exit(1) or anything not equal to 0 as a program exiting with 0 as error code mean everything went right which is not the definition of an exception.
I am not sure I understand the syntax behind all of this
Basically what you do here is throw an exception so you have two choices, either catch it or re-throw it but anyway it will have to be caught somewhere. Then in the catch you simply end the program returning an error code meaning that something failed System.exit(1)
See this Difference in System. exit(0) , System.exit(-1), System.exit(1 ) in Java for a better understanding of error code.
If MissingRightParenException is a checked exception (that seems to be the case, otherwise your IDE wouldn't be "nagging") then either you have to wrap it inside a try ... catch block or declare it via a throws clause in the method definition. The latter allows you to "bubble up" the exception and catch in the caller of your method throwing the MissingRightParenException exception.
Did you think about a throws clause?

Try/Catch inside or outside functions

I have a very basic question about best practice of using try/catch.
I have a simple function (DAO) like this:
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
and using DAO function inside web service:
#WebMethod(operationName = "addVehicle")
public void addVehicle(Vehicle vehicle) {
try {
vehicleDAO.addVehicle(vehicle);
System.out.print("Vehicle added");
} catch (Exception e) {
e.printStackTrace();
}
}
OR is better using try/catch inside DAO function like this:
public void addVehicle(Vehicle vehicle) {
try {
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
There is no perfect rule for that.
Often code is clearer and less complex if exceptions are catched as early as needed, but as late as possible.
You should think who has to take an action when that Exception happens, this decides if you catch it inside the method (addVehicle) or if you throw it such that the caller has to catch it.
E.g:
public void addVehicle(Vehicle vehicle) throws SQLException{
em.getTransaction().begin();
em.persist(vehicle);
em.getTransaction().commit();
}
In this example the caller has to catch.
Further only in few situations you should catch Exception or RunTimeException, better
catch that specific Exception, like IOException instead of Exception.
Somewhere in your code you will need a "last line of defense" where it make sense to catch (Exception ex). This is needed to handle errors that should not happen.
When deciding where to handle a specific kind of exception, the best rule of thumb is to stop looking at the micro details of your code, take a step back to reason about your program's logic and consider these things:
Is the exception something that your program's current operation cannot recover from? If yes, it only makes sense to put the exception at the topmost level of that operation, to ensure that it doesn't continue.
If your program can work around that particular exception (perhaps by trying something else before giving up), take each layer of nested functions (starting from the highest) and each time ask yourself: If the exception occurs during the execution of some line of code in this function, would it make sense for this function to continue? As long as the answer is "yes", move to the deeper level. As soon the answer is "no", chances are this is the best place to put the handler for that exception.
Alternatively to the previous one, you could decide what would your program's alternate "plan of attack" be in case the exception is raised. Then, go to the line of code that would raise that exception and ask yourself: Does this function have enough context information to perform the workaround I have in mind? As long as the answer is "no", move to the caller function. As soon as the answer becomes "yes", consider putting your exception handler there.
That being said, you should only catch reasonably specialized exceptions and keep the catch(Exception ex) construct only as a last resort only at the top level and only after all the other possible catch blocks, reserving it only for kinds of exceptions you really couldn't predict at the time of writing. (I know you said this is not the point of the example, but since we're at it, I thought it should be mentioned to make this answer more complete.)
You should only catch those exceptions which you want to handle. You may include a topmost exception handler to turn any unhandled exceptions into something somewhat useful for the end user.
Instead of e.printStackTrace();, try return proper exception message.
find out more about exception handling here
Here is more discussion about exception handling.
AFAIK the best practice will be smth like that:
public void addVehicle(Vehicle vehicle) {
em.getTransaction().begin();
try {
em.persist(vehicle);
em.getTransaction().commit();
} catch (Exception e) {
if (em.getTransaction().isActive()) {
try {
em.getTransaction().rollback();
} catch (Exception e) {
// Log rollback failure or something
}
}
throw new RuntimeException(e);
}
}
Use both, the only reason is to use catch RuntimeException or even Throwable. Because this kind of exception is typically thrown by the underlying frameworks. An you should catch exactly this kind of exception if you want to make some actions, for example logging, print stack trace, etc., before you re-throw it again. If you don't do in such way you may loose the cause of exception.
#Transactional
public void addVehicle(Vehicle vehicle) {
try {
//do whatever with session
} catch (RuntimeException e) {
e.printStackTrace();
throw new Exception(e);
}
}

Declare method to throw an exception and subclass of this exception

Is it meaningful to declare a method to throw an exception
and a subclass of this exception,
e.g. IOException and FileNotFoundException?
I guess that it is used in order to handle both exceptions by a caller method differently.
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
Absolutely. You can still catch them separately:
try {
methodThrowingIOException();
} catch (FileNotFoundException e) {
doSomething();
} catch (IOException e) {
doSomethingElse();
}
So it makes no difference to what the caller can do if the method declares both - it's redundant. However, it can emphasize exceptions that you might want to consider. This could be done better in Javadoc than just the throws declaration.
Is it meaningful to declare a method to throw an exception and a subclass of this exception, e.g. IOException and FileNotFoundException?
Usually not - most IDEs I know of even issue warnings for such declarations. What you can and should do is to document the different exceptions thrown in Javadoc.
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
Yes it is, you just need to ensure that the catch blocks are in the right order, i.e. more specific first. Catch blocks are evaluated in the order they are defined, so here
try {
...
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}
if the exception thrown is a FileNotFoundException, it will be caught by the first catch block, otherwise it will fall to the second and dealt with as a general IOException. The opposite order would not work as catch (IOException e) would catch all IOExceptions including FileNotFoundException. (In fact, the latter would result in a compilation error IIRC.)
However, is it possible to handle both exceptions if the method throws only the most generic i.e >IOException?
catch(IOException ex){
if(ex instanceof FileNotFoundException){}
}
But this doesn't look clean, Throwing both exception looks good, even caller would come to know to that this method may throw these these exceptions, so they will handle it properly
Yes, it's possible to handle both if the method only throws IOException.
The best way to answer such a question is to write a test to demonstrate it and try it out. Let the JVM tell you the answer. It'll be faster than asking here.
yes. when certain specialized exceptions can be handled correct. It is, if you handle the exceptions as follow:
try {
} catch (FileNotFoundException f) {
//Try a different file
} catch (IOException ioe) {
//Fatal, Maybe bad blocks ... Bail out...
} catch (Exception e) {
//Something went wrong, see what it is...
}
Declaring, that the method may throw (more generic) IOException, and (more specific) FileNotFoundException is usually a good thing - it's an additional information for people using your code later. Note that you should explicitely state in the JavaDoc, under what circumstances is each of the exceptions thrown.
They will still be able to distinguish the exceptions, and handle them differently using catch constructs like this one:
try {
yourAwesomeMethod()
} catch (FileNotFoundException ex) {
// handle file-not-found error
} catch (IOException ex) {
// handle other IO errors
}

How do I diagnose "Unhandled Exceptions" in Java?

In a Java program I am currently getting "Unhandled Exception" at a certain point in the program and I can't seem to determine the location where this is being generated.
Its also difficult to debug the code as the program contains streams that handle wireless data bytes sent and received. I can't seem to simulate that with a debugger.
What strategy should I adopt to locate the Exception?
Implement the Thread.UncaughtExceptionHandler interface and use setDefaultUncaughtExceptionHandler() to set it.
Sample program as courtesy. If you use multiple threads you also could just set the handler on threads you suspect to be the culprits.
public class Test {
public static void main(String args[]) {
new Test();
}
public Test() {
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
// or if a default handler is set you can also use setUncaughtExceptionHandler
// check the javadocs for the specifics
throw new RuntimeException ("You can't get me or can you?");
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.err.println ("Uncaught exception by " + t + " caught:");
e.printStackTrace();
}
}
}
You could put a try-catch(Exception ex) block around sections of code and move it around/tighten the block and have it log the exception being thrown. As long as there isn't too much code you should be able to track it down in a few runs.
But as I run the program the device
shows "Unhandled Exception" and asks
me whether to close the app.
First you need to find the place in the code that is generating this message. It sounds like the app has a GUI or whatever, so it is possible a Dialog of some kind.
Next, find the place in the code that is causing the message/dialog to be created. It is likely to be either
a try / catch block that catches Exception or Throwable, or
an UncaughtExceptionHandler.
In either case, the next thing is to add some code to cause the app to output a stacktrace for the uncaught exception. Assuming that ex holds a reference to the exception object:
ex.printStackTrace();
will write a stack trace to the standard error stream; e.g. the "console". (There are more heavy-weight solutions if you cannot find where "console" output goes to.)
Sounds like you've got an unchecked RuntimeException happening somewhere. You could easily try it in your main() method with try { } catch(Throwable t) { t.printStackTrace(); }
Or if you remotely debug it with an IDE like Eclipse, you can set it up to trigger the debugger on a Java exception breakpoint with "Suspend on uncaught exceptions". Some docs here.
If you don't have a stacktrace, you can't do much.
If it is actually caused at the other side and you received this as a message, then you should ask the other side for a stacktrace or similar information.
Edit: you should of course ensure that your own code isn't swallowing exceptions like as:
} catch (Exception e) {
// Do nothing.
}
or
} catch (Exception e) {
System.out.println("Error");
}
or
} catch (Exception e) {
System.out.println(e.toString());
}
To get the most information out of exceptions, you should do at least:
} catch (Exception e) {
e.printStackTrace();
}
or just
} catch (Exception e) {
throw e;
}
Hope this helps.

Handling Multiple Exceptions within a Method

I am currently working on the maintenance of a piece of code that is a little bit "Exception Happy." Basically, ever method or anything throws Exception. I'm going to work to take care of that, but, in the meantime, I am wondering what is the best way to handle individual exceptions within a smaller block of code, such as a method. Is it better to do something like this:
public void aMethod()
try {
//Lots of code in here. Many lines.
} catch(Exception e) {
// TODO - Handle All Exceptions, but fairly generically
}
}
Or something like this:
public void bMethod() {
try {
// One line of code.
} catch(Exception e) {
// TODO - Handle a specific Exception (may even involve rethrowing it with more information)
}
// More code.
try {
// Another line of code.
} catch(Exception e) {
// TODO - Handle another specific exception.
}
}
I realize this is a pretty basic question, but after looking at hundreds of methods with Exceptions coming out of every one, I'm starting to wonder how best to handle all of them and what a best practice may be here.
First off, you should only put code in try/catch blocks that is exception worthy. For instance, having an unexpected value is not necessarily an exception, but trying to read from a file that doesn't exist is.
To answer your main question, you should put the exceptionable code in the same try {} block and catch specific questions in order of granularity in multiple catch blocks after the main try.
//Regular code that doesn't need to be covered by a try/catch block
try {
//critical code only
} catch (NullPointerException npe) {
//Code
} catch (RandomException re) {
//code
} catch (Exception e) {
//code
}
The answer to your question is: it depends.
if the code in the try block is coherent where it makes no sense to proceed in the event of an error, the first approach is best
if the code is taking seperate steps that are relatively unrelated (parsing numbers for instance) and can be recovered without aborting the rest of the method the seconds appraoch makes sense
A general remark on the code you inherited; it sounds like exceptions are abused to pass state around, I would refactor so that exceptions are caught at the spot where they can be handled and introduce return values or attributes to handle the state.
your bMethod isn't very useful illustration. Try to reprase it. Anyway, you have two options:
catch exceptions and log them.
catch exceptions and throw new RuntimeException(ex) (rethrow a runtime exception, setting the original as a cause)
Also, you will need to differentiate between exceptions. If your system has many custom exceptions, they are probably defined for a reason, and specific behaviour is expected when one of them is thrown.
If the try/catch block isn't adding useful information, just allow the method to throw the exception and have it handled where the caller can sensibly do something with the exception. This could cut down the number of try/catch significantly (by an order of magnitude).
BTW a trick for rethrowing any exception is.
try {
// do something
} catch (Throwable t) {
Thread.currentThread().stop(t); // rethrow any exception.
}
In addition to the suggestions already made you may also want to consider extracting try/catch blocks from the "meat" of the function.
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
}
catch (Exception e) {
logError(e);
}
}
private void deletePageAndAllReferences(Page page) throws Exception {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
logger.log(e.getMessage());
}
This lets you focus your attention on the function you are really interested in without the exception handling getting in your way.

Categories