Global Exception Handlers in Java - java

I am thinking of setting up a global, default Exception handler for my (Android) Mobile application(which uses Java syntax) using Thread.setDefaultUncaughtExceptionHandler(...) call. I am thinking of just displaying an Alert Dialog with appropriate message to the user.
Are there any gotchas, caveats and rules that one needs to follow when setting DefaultExceptionHandlers? Any best practices like making sure that the process is killed, full stack trace is written to logs etc. ?
Links to documentation, tutorials etc. that can throw some light on this are welcome.
Thanks.

The name is a bit misleading, because using that method will set a default exception handler for all threads.
Make sure no exceptions can be thrown from your exception handler.
If you're doing GUI stuff from your exception handler, make sure you're doing it from the right thread.
An uncaught exception will only stop the thread where the exception took place, if that also causes the process to terminate depends on any other threads that might be running.

One possible problem with creating a global exception handler is you may get stuck in a loop of exceptions - some exceptions will be thrown repeatedly unless a program is terminated.
If you mean that when an exception is thrown, a message is displayed then the app is terminated, then you'll be fine.

Related

Error handling at a higher level

I have try/catch blocks at lower levels to handle most errors, but I was told we need one near the top, basically as a catch all to allow the program to continue operating correctly if there is an error. I put a try/catch(Exception e)/finally around everything at the top level, but we are still getting exceptions causing crashes. I've been looking at the stack trace for any clues... It starts like this (I can post more of it if that would help):
111858 [SimpleAsyncTaskExecutor-2] DEBUG o.h.e.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("DATABASE"."TABLE"."COLUMN")
The weird thing is that the rest of the stack trace never goes back to anything that is ours. It's all oracle/apache/hibernate/springframework until it ends up with:
at java.lang.Thread.run(Thread.java:795) [na:1.7.0]
Any ideas why it's not going back to our code or how better to implement this "catch all"? The finally block is for some steps that we want to implement whether there is an error or not.
Edit: for clarity's sake and because maybe it will help, this is part of a batch that processes files every 5 minutes. The try/catch is like so:
try{
//process file
}catch(Exception e){
//log exception
}finally{
//mark file as processed so it doesn't keep trying to reprocess a broken file
}
You, or a library that you are using must be spawning off a thread somewhere and it is that thread that is throwing the exception.
Your options are
track down the creation of that thread, and handle the exception from there
track down which thread group that the thread belongs to and register an exception handler with that thread group
The best idea I can suggest for implementing this "catch all" is don't do it.
I would, instead, recommend defensive programming at the class level. Each class should handle its own possible exceptions when possible. This will save you time later when something goes wrong and you have to track down where to came from.
You need to debug and find where the thread is being created and handle exceptions there.

Is it possible to handle all Errors in Java?

I know that Error is Throwable (so it can be handled) and Error handling isn't best practice but suppose we have a requirement to catch all Error.
It is possible in general? I mean what about Errors which can appear in daemon threads? They will crash jvm and I won't know about it.
And can I miss Error even if I surround main(String... args) with try-catch?
You can catch the uncaught exceptions via Thread.setUncaughtExceptionHandler()
Set the default handler invoked when a thread abruptly terminates due
to an uncaught exception, and no other handler has been defined for
that thread.
Uncaught exception handling is controlled first by the thread, then by
the thread's ThreadGroup object and finally by the default uncaught
exception handler. If the thread does not have an explicit uncaught
exception handler set, and the thread's thread group (including parent
thread groups) does not specialize its uncaughtException method, then
the default handler's uncaughtException method will be invoked.
Whether that's a good idea is another question (!). It may be that you simply want to clear up resources, shut down connections etc., log the issue and/or alert the user. If you do have critical issues like OutOfMemoryErrors then there's little else you can do.
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.
Now, since Error does indeed extends Throwable, it is possible to catch 'any' error via a simple try-catch statement as follows:
try{
//Error causing code here...
}catch(Error e){
//Handle error here...
}
However, since errors come in different forms, a thrown error may or may not be accompanied by a change in the jvm's behaviour to cause unexpected results.
Consider the Error OutOfMemoryError. When this Error is thrown, the JVM's heap may be so full that any type of handling code results in another OutOfMemoryError being thrown, voiding any attempt of recovery.
Furthermore, even when running on the "primary" thread (the one the application starts in), a error could cause a JVM to crash before every throwing a Error.
Looking at the description of VirtualMachineError (of which Errors such as OutOfMemoryError, StackOverflowError, InternalError, etc are subclasses of) we see:
Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating.
The javadoc itself states that the jvm no longer can continue operation normally much less allow a programmer to just 'handle' them away.
On the other hand, errors such as UnsatisfiedLinkError generally do not cause a problem with the jvm straight away and can generally be handled (whether this is good practice is debatable). I personally have once used a structure that involves handling a UnsatisfiedLinkError to determine the correct library to load for JNI.
Now, can all errors be handled? Theoretically yes, if we assume that the JVM can continue operation perfectly despite claiming to have failed fatally... With that in regard, practically only a small subset of errors are handleable. Whether or not these small subset of errors should be handled is also a highly controversial topic.
You can handle exceptions, but you can't handle errors.

Printing exceptions thrown by thread-pool threads, Java's default behavior

I asked this question: Printing the stack trace from a newly created thread when an unchecked exception is thrown in Eclipse
And got this in a reply by the user Gray: "By default there is nothing that prints the exceptions thrown by thread-pool threads."
I'd like to know the reason why that is. It seems confusing to me to have a thread-pool thread throw an unchecked exception and stop working without printing any errors by default.
One would have to alter the program, for instance a Thread has a set(Default)UncaughtExceptionHandler.
With AOP one could achieve such a thing.
Because if it printed it, another developer would ask why it cripples the output of the program with unwanted stack traces, and reduces the throughput drastically by writing the stack traces to a synchronized PrintStream. If you want the exceptions to be printed, then print them by yourself. Nothing prevents you from doing it.
The answer you got shows how to do that. You could also wrap all your runnables with another runnable that catches the runtime exceptions, prints them when they are thrown, and rethrow them.

Java Error handling - is it better to throw Exceptions to centralized error handlers?

I've got a decently complex little game going on in Java (solitaire, essentially like the Windows version), but I have yet to do very much error handling.
Almost all of the methods across my classes will end up either getting called by an initial constructor (eventually main()), a paintComponent() method, or a mouse event. So, my question is, is it bad practice to just use "throws Exception" on all of my lower-level methods, and only do a try/catch at my top-level methods to catch ALL the errors at once? (e.g. 3 try/catches - one for the painting, one for mouse events, one for the main method).
I realize this prevents me from easily dealing with errors on-the-spot, but I don't really plan on doing that anyways. My error handling is going to consist of writing to a log, telling the user, and killing the program. Keeping this in mind, is there anything bad with doing my error handling this way?
It depends on how you want to approach the situation.
If you just want to catch any possible exception and you don't mind about the handler code, you could simply use "throws exception", and there's nothing BAD with it either. It's like a try-catch block that covers all the function.
If you want to write specific code for specific exceptions, you should use try-catch blocks to write appropriate code for each handler.
Based on what you're saying, any caught exception would just notify the user and exit the application. Well, in this case you could just use the first approach. It's not necessarily the BEST approach, and neither is killing the application, however, if that's your strategy you could just use "throws" for each function.
Hope that helps!
If that's all you wan't to do in a case of an error, then it makes perfect sense to do it that way. This eliminates code duplication and scattering of related code. However, if you're thinking of changing how things work in the future (if there's a possibility of this happening), I would suggest to try and push the catch down as far as possible (maybe even eliminating the need for exceptions at all and just logging and exiting right away).
If you use the exception's inner fields (specifically message, which you can set in construction time), you can even eliminate the need for 3 different catch blocks and just use one (depending on your actual actions in case of an error, of course).
I wouldn't - the big reason being that it breaks encapsulation. The reason why this is important in this case is that your error handling code has one of two futures:
Becoming enormous to handle in an informative way every error the program can throw.
Be tiny but not helpful at all: "Some error occurred somewhere".
To my mind, the best structure is to catch the error, log it, alert the user, and exit as far down as possible. There's nothing that says your mouse handling code can't exit, right?
In fact, I would create an error handler class that you can call from just about anywhere, and it handles the notification and logging. Then your exception handlers can just populate it with the message to display/log, and all other code is shared. It will cost you less typing to delegate to this class than adding throws Exception at the end of every function everywhere.
If you must have a top level handler, it should just catch any unexpected runtime errors, so that you can log it and show the user that the program is really quitting for an error, and not just dump to the desktop. All other errors - even if you just want to bail out - should be caught as close to "where the exception has meaning" as possible.
I do the same thing as you are describing most of the time. What you're basically doing is working around the stupid checked exceptions that Java has. It shouldn't even be necessary to add 'throws Exception' everywhere.
If I'm working on an API that other users will use I may create specific exceptions to show what is going on in case they want to handle different exceptions in different ways.
If an error is severe enough to always exit the program, you may be better of throwing a RuntimeException instead. They are used to indicate unrecoverable errors and will avoid problems with putting "throws Exception" everywhere. You should have a handler for RuntimeExceptions anyway to provide a user-friendly error report in case they happen.
If you throw checked exceptions, they should be as specific as possible. Throwing and catching Exception can hide other exceptions that are thrown (including RuntimeExceptions) that you didn't intend and could have been handled differently. If you want to throw a general exception, you can always create your own exception class and throw that instead.
The exception handling can depend on the context so there's not one way to handle everything. If the user clicks a button to open a file and there's an error reading it, then it would be ok to throw an IOException up to the UI layer and display an error message there. On the other hand, an IOException while creating a temporary file could be handled lower down by retrying in another directory.

Uncaught exception within uncaught exception handler

This question may sound a little silly ;)
How would approach the possibility of an uncaught exception within the UncaughtExceptionHandler?
Very interesting question, I haven't thought about this before.
The approch seems to be that either set your own uncaughtExceptionHandler on your thread or it will get passed to JAVAs defaultUncaughtExceptionHandler,
I made some quick googeling and found a similar case for getting crash data from android.
I think you may be intresing in this link How do I obtain crash-data from my Android application?
Well, you have to catch them yourself. The documentation of uncaughtException() linked by you states this clearly:
Any exception thrown by this method will be ignored by the Java Virtual Machine.
But you can only plan so far. So you handle the exceptions of your exception handler but who handles that code? It's the same with logging a failed logging event. Exception handlers all the way down...

Categories

Resources