Java: Call method on all caught exceptions [duplicate] - java

This question already has answers here:
Java: Global Exception Handler
(6 answers)
Closed 8 years ago.
I know I can set my own UncaughtExceptionHandler to execute code on uncaught exceptions, but is there a way to have some code execute on all caught exception without having to call that method in every single try-catch block?
My custom code sends me an email with the stack trace on uncaught exceptions. I also want that email for caught exception but I don't want to track down every single try-catch statement and add it.
I'm not looking for a global exception handler (I mentioned UncaughtExceptionHandler), I'm looking for a global CAUGHT exception handler.

You can do it by altering the Exception class to record every Exception. This can be done by changing the boot class path, runtime code injection or using the JVMTI.
I suspect it's a bad idea as the system will catch more exception than you might expect. You could get thousands of emails a second if something goes wrong.

I suggest you revisit your exceptions handling policy and strategy. When an exception happens it generally means something went wrong, i.e., something exceptional (as in unexpected) happened in the code (database connection lost, file not found, network unreachable, etc.) or a bug in the code causes an unexpected problem (NPE comes to mind...). In these scenarios the normal program flow can't continue.
It's usually considered best practice to fail fast in such cases, unless you are expecting some exception to be thrown and know how to recover, i.e., the exceptional condition wasn't that exceptional after all.
If you need to fail fast, you don't need to explicitly handle the exceptions as your thread or program will just die and you can just use the UncaughtExceptionHandler to log the stack trace, send emails or notifications etc.
Situation in which you can successfully recover and resume the normal program flow are far less common in my opinion and usually do not require developers/ops to be notified as it is part of the normal functioning of the system (otherwise you would not be able to handle the exception). So simply logging the specific message and useful data associated to this scenario is usually enough, e.g., "WARNING: Transient error x was recovered. State was y and z.".

Related

How can I make program print a stack trace automatically when an Exception occurs in Android

Is there a way I can automatically print a stack trace when Exception occurs? I understand I can do so by manually surrounding a block with a try-catch statement, but there's no prior-knowledge where an exception would happen in a program, and doing it in suspicious region block by block would be super inefficient, since there're potentially many. So is there any configuration option or any programmatic way to do so in Android?(like surrounding a try-catch block in the highest level of method?, but what's the highest level of method)
Define a global exception handler in your Application class and add any code you need to it.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
It is recommended that you still re-throw caught exceptions so that the app stops running, because it will be in an unstable state and not doing so can cause the app to freeze up.
catch (Exception e) {e.printStackTrace();}
The highest level is the Application level I believe. But in general just catch it at the usual activity lifecycle should be sufficient.
Extend Exception and do whatever you want in your custom Exception class.
There are two major kinds of exceptions:
Exceptions caused by programming errors (e.g. dereferencing a null reference, ...)
Exceptions caused by the environment (e.g. user enters 'abc' in a numeric field, network cable was unplugged, ...)
In most of the cases you can't really recover from the first ones. (If something unexpectedly went wrong, how can you know what to do to recover safely?) This are usually unchecked exceptions and you don't have to catch them somewhere.
Uncaught exceptions are catched by the system/framework and logged automatically!
Take care for the second type of exceptions! They are mostly not unchecked and have to be either cached or specified via throws clause. Handle them, probably log them, and try to recover if possible.
This document explains how you can read the error log and other logs on android devices. There are also apps available that can display the log on the device itself.
Also read this basic exception tutorial!

Java Asynchronous Exceptions: Can I catch them?

I have been reading the JLS and I encountered the section 11.1.3. Asynchronous Exceptions from which I quote:
Most exceptions occur synchronously as a result of an action by the
thread in which they occur, and at a point in the program that is
specified to possibly result in such an exception. An asynchronous
exception is, by contrast, an exception that can potentially occur at
any point in the execution of a program.
And
Asynchronous exceptions occur only as a result of:
[...]
An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the
Java programming language. In this case, the asynchronous exception
that is thrown is an instance of a subclass of VirtualMachineError.
Is it possible to catch such exceptions for logging purposes or notification (because I believe such thing is unrecoverable)? How can I achieve such thing?
You can catch such exceptions just like any other exception. The only problem is that they may occur at any place in your program, so catching them reliably is hard. You would basically have to wrap the run method of all threads and the main method in a try..catch block, but you can't do that for threads you don't control (like the Swing EDT, or threads for timers etc.).
Also catching any subclass of Error is usually not recommended, because the JVM may be in an unstable state, which might lead to a further failure (for example in the case of OutOfMemoryError, you might not even have enough memory to to the exception handling). However, logging would be a valid reason for catching Errors in my eyes.
My suggested solution would be to use an uncaught exception handler for this by setting it as the default exception handler. In this handler you will get all exceptions and errors, if they are not caught anywhere in the code, and you can try to log them.
There is no point of catching these exceptions (Subclasses of VirtualMachineError) as you have no indecattion in which state the pogram is at the point, the Doc saies about Virtual Machine Errors:
A Java virtual machine implementation throws an object that is an
instance of a subclass of the class VirtualMethodError when an
internal error or resource limitation prevents it from implementing
the semantics described in this chapter. This specification cannot
predict where internal errors or resource limitations may be
encountered and does not mandate precisely when they can be reported.
so assuming you get in an OutOfMemoryError or an UnknownError there isnt much you can do about it, and once your vritualmashine doesnt work properly you cant provide the user anyhelp as your program isnt working properly as well, besides you have no idea at what time, point, and reason it happends since its not a code error that was caused from your program.

How are un-checked exceptions reported to the user

Since there is no need to try/catch or specify un-checked exceptions, how are they are reported to the user?
how are they are reported to the user?
What is the best practice to handle
un-checked exceptions?
In our application, we barely use any exception at all: neither checked nor unchecked (we consider checked exceptions to be a Java idiosynchrasy unrelated to the problem domain we're dealing with, so we wrap most checked exceptions inside cleaner APIs, using state testing methods).
The way we deal with it is simple: it's a desktop application, if we catch an uncaught exception, we offer the user the possibility to send us a report. All the user has to do is click on "Report" and we get the full stack traces and other infos sent to one of our servers.
You can set up an application-wide uncaught exception handler like this:
Thread.setDefaultUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() {
public void uncaughtException( final Thread t, final Throwable e ) {
...
// Here we offer our user the possibility to 'report' the exception, YMMV
}
}
Typically there are zero exception happening in our software: we don't use checked exception for flow control (unless when we're using brain-dead APIs from the nineties, where this was common practice).
Some frameworks, like Spring, also have a pretty strong preference towards the "no checked exceptions" mentality.
So exceptions for us are really exceptionnal, hence the popup warning the user that the app crashed and offering them the possibility to send us the report.
If you are writing a container or a framework or a UI framework, then the best place to handle them is centrally, propagate them all the way to central handler and report the error to user in a usable way,
If using a UI, provide a way for user to report that exception.
Details:
We generally use a practice when using UI is that have a central exception handler.
In case of a web UI, we have on handler that shows the user that something has gone wrong in the system, The error page also has a form with hidden fields that has stack trace along with a description (optional) field asking the user to describe what she/he was doing when error occured. The for submits the error information, with stacktrace to the system (which can be a mail or simply stored in db)
In a desktop UI, could be the same, only thing that will be different is where you put your exception handling code.
Error reporting example
Error reporting example http://www.flickr.com/photos/aniketn/4785197367/
You actually can catch unchecked exceptions. It's just that they're usually things you can't solve when you do catch them - for example, NullPointerException. There's generally not a way to smoothly and gracefully resume whatever you were doing when the NullPointerException occurred.
If you don't handle them, they will propagate all the way up through your program and it will abort, dumping a stack trace of the exception.
The best practice is to deal with the ones where you can provide some better handling than the default. For example, if you call an external library function, you could wrap it in a try/catch block and if the library throws a NullPointerException you could give the user a friendly error message (a GUI "library X failed to do Y - did you specify a valid Z?") instead of a stack trace on the command line. But in the general case, the reason they're unchecked is because even if you knew about them, there'd be nothing for it but to throw up your hands.
When bubbling out of the main(...) method, the JVM prints the stack trace to System.out and exits that thread. For single-thread programs, that would also exit the program.
In general, every thread you run should have a wrapper catching Throwable so you can at least log it to your files.

When is it OK to catch a RuntimeException

On a recent project I recommended catching a RuntimeException within a test harness code and logging it. The code processes a series of inputs from a database, and I do not want the test to stop due to failure of any one input (Null values, Illegal arguments, etc.). Needless to say, my suggestion triggered a passionate discussion.
Is catching any kind of RuntimeException acceptable? If yes, what are other scenarios where it is OK to catch RuntimeExceptions?
You catch RuntimeException for the same reason that you catch any exception: You plan to do something with it. Perhaps you can correct whatever caused the exception. Perhaps you simply want to re-throw with a different exception type.
Catching and ignoring any exception, however, is extremely bad practice.
Unless you can correct a RuntimeException, you don't want to catch it...
...only true from a developers point of view....
you have to catch all exceptions before they reach up to the UI and make your user sad. This means on the "highest level" you want to catch anything that happend further down. Then you can let the user know there was a problem and at the same time take measures to inform the developers, like sending out alarm mails or whatever...
It is basically considered a data/programming error that could not be forseen, thus you want to improve future releases of the software while at the same time take the user by the hand and move on in a controlled manner...
RuntimeException is intended to be used for programmer errors. As such it should never be caught. There are a few cases where it should be:
you are calling code that comes from a 3rd party where you do not have control over when they throw exception. I would argue that you should do this on a case by case basis and wrap the usage of the 3rd party code within your own classes so you can pass back non-runtime exceptions.
your program cannot crash and leave a stack trace for the user to see. In this case it should go around main and around any threads and event handling code. The program should probably exit when such exception occurs as well.
In your specific case I would have to question why you are having RuntimeExceptions occur in the tests - you should be fixing them instead of working around them.
So you should guarantee that your code only throws RuntimeExceptions when you want to have the program exit. You should only catch RuntimeExceptions when you want to log it and exit. That is what is in line with the intent of RuntimeExceptions.
You can look at this discussion for some other reasons that people give... I personally haven't found a compelling reason in the answers though.
In my code 99% of my exceptions are derived from runtime_exception.
The reasons I catch exceptions are:
Catch Log and Fix problem.
Catch Log and Generate a more specific exception and throw
Catch Log and rethrow.
Catch Log and Kill operation (discard exception)
User/request initiated action fails.
An HTTP request handler for example. I would rather the requested operation die rather than bring the Service down. (Though preferably the handler has enough sense to return a 500 error code.)
Test case passed/failed with an exception.
All exceptions not in the main thread.
Allowing exceptions to escape a thread is usually badly documented but usually causes program termination (without stack unwinding).
Years ago, we wrote a control system framework and the Agent objects caught runtime exceptions, logged them if they could and continued.
Yes we caught Runtime exceptions including OutOfMemory in our framework code( and forced a GC, and it's surprising how well that kept even quite leaky code running.)
We had code that was doing very mathematical things involving the real world; and from time to time a Not-A-Number would get in due to tiny rounding errors and it coped okay with that too.
So in framework / "must not exit" code I think it can be justifiable. And when it works it's pretty cool.
The code was pretty solid, but it ran hardware, and hardware tends to give screwy answers sometimes.
It was designed to run without human intervention for months at a time.
It worked extremely well in our tests.
As part of the error recovery code, it could resort to rebooting the entire building using the UPS's ability to turn off in N minutes and turn on in M minutes.
Sometimes hardware faults need to power cycled :)
If I remember, the last resort after an unsuccessful power cycle was it sending an email to it's owners, saying
"I tried to fix myself and I can't; the problem is in subsystem XYZ", and included a link to raise a support call back to us.
Sadly the project got canned before it could become self aware :)>
Personally, I've always been told that you want to catch all RuntimeExceptions; however, you also want to do something about the exception, such as running a failsafe or possibly just informing the user that an error occurred.
The last Java project that I worked on had a similar approach, at the very least, we would log the exception so that if a user called complaining about a bug, we could find out exactly what happened and see where the error occurred.
Edit 1: As kdgregory said, catching and ignoring are two different things, generally, people are opposed to the latter :-)
We all know that checked exceptions and RuntimeExceptions are the two categories of exceptions. It is always suggested that we handle (either try-catch or throw) the checked exceptions because they are the programming conditions where unfortunately programmer can not to do anything on its own;
Like FileNotFoundException it is not the programmer who puts files on user's drive if program is actually trying to read the file 1.txt which is supposed to be there on f:\ of user with the statements:
File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);
If the file is found it's all ok, but what happens in the other case if the file is not found is that, program crashes down with 0 error from the user. In this scenario programmer did not do anything wrong. This could be a checked exception which must be caught for the program to continue running.
Let me also explain the second scenario with which the concept of RuntimeException will be clear. Consider following code:
int a = {1,2,3,4,5};
System.out.println(a[9]);
This is poor coding which generates the ArrayIndexOutOfBoundsException. Which is an example of RuntimeException. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.
You catch RuntimeException when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.
You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of all the tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.
Another common situation is a server; you don’t want to shut down just because one request was malformed in a way you didn't expect. (Unless it’s really, really important to minimize the chances of inconsistent state.)
In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.
One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do after catching it: how your program should continue.
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.
Here's the bottom line guideline.
From Java Docs. Please read this Unchecked Exceptions — The Controversy

beginner question about exception in java

when an exception occurs that a method is unable to handle - does the program terminate and show the error number ? where does the error number and information about the error come from ? should the programmer while coding have an idea what kind of exception might occur. if so why does'nt he ensure that exception does not occur .
If you are using Java APIs, the exceptions that each method throws are documented.
When the program terminate, it shows an stacktrace of the methods calls that caused that specific problem.
Check the lesson on Exceptions from The Java Tutorial. You can learn much more reading there than reading my answer here :)
There are 2 main types of exceptions in Java:
- checked
- unchecked
unchecked exceptions are further broken into RuntimeException and Error.
RuntimeExceptions are programmer errors (ArrayIndexOutOfBoundsException) and Errors are things that are problems in the VM (OutOfMemoryError).
You should not catch RuntimeExceptions - you should fix your code so it does not throw the exception.
You should not catch Errors since the VM is likely in a state that you cannot do anything to recover from them.
If your main does not catch an unchecked exception it will crash.
Java Exceptions bubble-up to the point where someone catches them, or to the point the program exits.
In the real-world, when many frameworks are used, exceptions never bubble-up to the top. They are caught and reported (printed on console). Catching exceptions is done by the try { } catch(..) { } block.
There are two types of exceptions - checked and unchecked. The checked exceptions must be declared in the method signature (unlike the unchecked)
should the programmer while coding
have an idea what kind of exception
might occur
Yes, but no one's perfect.
why does'nt he ensure that exception
does not occur
In exceptional circumstance, you WANT an exception. You do not want to ignore the exception.
For example, suppose that your program creates a file to save user settings. If for some reason
the file creation fails (which your program has no control over, it's the Operating System's job), you do not want to go on like nothing happened. You want there to be an exception, so that whoever or whatever function called that function knows about this problem, and can do something, e.g. inform the user.

Categories