Chained Exception versus PrintStackTrace - java

Chained Exception is useful in cases in which knowledge of an underlying cause is useful. The Throwable getCause( )method returns the exception that underlies the current exception.
On the other hand, if we call PrintStackTrace() in the catch block, we will have the entire logs printed in the logger file(and in eclipse console). The detailed log will show the exception occurred, and the underlying chain of exceptions as well.
So, what is the primary difference in the usages of both of them.

One approach is to provide debug information (PrintStackTrace). The other approach is for actual flow control (Throwable.getCause()).
(Usually) the underlying cause is considered an implementation detail, and therefore should not be used for flow control. Add the information you need to the main exception or create multiple types for exception.

Related

Is it a good practice to use nested exceptions?

This is probably a broad question, not quite SO style, but I'd still like to get some hints or guidelines if possible.
I've been looking through some legacy code and found a part of it that has methods with exceptions nested 3 or 4 levels down.
Is this considered to be a normal practice or should one avoid such codestyle where possible? If it should be avoided, what are the negative effects besides the increasing costs of exception handling and decreasing readability? Are there common ways of refactoring the code to avoid this?
I personally prefer the following ideology
Wrap Alien Exceptions
An "alien" exception is an exception thrown by a Java API or a third party library. In other words, an exception you do not control.
Its better to catch all alien exceptions and wrap them in an appropriate application specific exception. Once the alien exception is converted to your own exception, you can propagate that exception any way you like.
Rethrowing Checked Exceptions can get Messy
If your application uses checked exceptions, rethrowing the original exception means that the method rethrowing it must also declare it.
The closer you get to the top of the call hierarchy, the more exceptions will be declared thrown. Unless you just declare all your methods to throw Exception. However, if you do so you might as well use unchecked exceptions, since you are not really getting any benefit from the compiler exception checking anyways.
This is why I prefer to catch non-application specific exceptions and wrap them in an application specific exception, before propagating them up the call stack.
Guidelines For Wrapping : The context in which an exception occurs may be just as important as the location of the exception itself. A given location in the application may be reachable via different execution paths, and the execution path may influence the severity and cause of the error, if it occurs.
If you need to add context information to an exception as you propagate it up the call stack, you need to use active propagation. In other words, you need to catch the exception in various relevant locations on the way up the call stack, and add the relevant context information to it, before rethrowing or wrapping it.
public void doSomething() throws SomeException{
try{
doSomethingThatCanThrowException();
} catch (SomeException e){
e.addContextInformation(“more info”);
throw e; //throw e, or wrap it – see next line.
//throw new WrappingException(e, “more information”);
} finally {
//clean up – close open resources etc.
}
}
Checked Exceptions should not be propagated up the stack or chained if possible. If a method is throwing a checked Exception its caller is supposed to handle it, if caller is not handling it and propagating it to its caller, then overall complexity increases.
In a three layered example : Dao , Service , Controller
DAO layer will throw DAOException
Service layer should not expose DAOException to Controller , instead it should be throwing relevant BuinessExceptions, which the Controller should be handling.
Exception handling tends to be an expensive way to handle flow control (certainly for C# and Java).
The runtime does quite a lot of work when an exception object is constructed - getting the stack trace together, figuring out where the exception is handled and more.
All this costs in memory and CPU resources that do not need to be expanded if flow control statements are used for flow control.
Additionally, there is a semantic issue. Exceptions are for exceptional situations, not for normal flow control. One should use exception handling for handling unanticipated/exceptional situations, not as normal program flow, because otherwise, an uncaught exception will tell you much less.
Apart from these two, there is the matter of others reading the code. Using exceptions in such a manner is not something most programmers will expect, so readability and how understandable your code is suffer. When one sees "Exception", one thinks - something bad happened, something that is not supposed to happen normally. So, using exceptions in this manner is just plain confusing.
Please take a look at below links
Exception Handling: Common Problems and Best Practice with Java 1.4 - pdf
Why not use exceptions as regular flow of control?
Best Practices for Exception Handling
Error Handling
Mr. Google Links
I've been looking through some legacy code and found a part of it that has methods with exceptions nested 3 or 4 levels down.
Is this considered to be a normal practice or should one avoid such codestyle where possible?
This is not a necessary process to handle your exception in this way, as it will increase your application overhead, until you really need to handle very specific exception(checked or Alien Exceptions) and you can ignore overhead to get specific information to handle that exception.
If it should be avoided, what are the negative effects besides the increasing costs of exception handling and decreasing readability?
As I mentioned you will not get specific information about the exception, if you are not going to use nested exception handling(throws with some added information to the upper handler) you may/may'not do specific action on behalf of some tough exception, but in nested case you can do action by handling that specific situation.
Are there common ways of refactoring the code to avoid this?
If you have a poorly factored program that does what the you want and has no serious bugs, for god sake leave it alone! When you need to fix a bug or add a feature, you Refactor Mercilessly the code that you encounter in your efforts. Override the Exception Class in your custom Exception Handler and add some added features to handle your problem.
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
Hop this will help you.
You should do away with the exception nesting. You should either avoid chaining the exceptions in the first place, or (selectively) unwrap and then rethrow the nested exceptions further up the stack.
About handling legacy code I would recommend you have a look at the book covering the topic:
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
You dont even have to go through the whole book, just look at the things that concern you at the moment.
Also a good book regarding good practices is:
http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?s=books&ie=UTF8&qid=1356340809&sr=1-1&keywords=clean+code
The best approach when handling nested exceptions is refactoring the code and using runtime instead of checked exceptions, and handling those where needed. This way the code is more readable and easier to maintain.
Its depend on the Business logic. You may take action on the exception there itself or you may propogate it all the way upto caller and leave it to the caller for what action he want.
e.g. There are lot of third party API where they don't handle the exception but they throw it from method and hence facilitate API users to take actions as per their need.
e.q. oracle JDBC driver. Driver.getConnection() throws exception. Now caller/API user can handle it as per their need. One may just print stack trace, one may notify admin asking for his attention or one may choose just silently exit the application.
There are two approaches:
To generate a separate exception for each event.
To create a generic exception and describe what caused it
The first approach allows you to write different code for handling the different events, but it requires you to write lot of Exception classes and in some case it could be just too much.
The second approach is more concise, but it makes it difficult to handle the different situations.
As it happens very often in programming the best solution is in the middle, where you balance generating separate exceptions and using one exception for other cases.
The rule of the thumb in this case could be to generate a separate Exception class for the exceptions you want to handle specifically with separate code.
Similarly to the what to throw, we should also have control on what to catch. We can use two approaches for our catch blocks:
A single catch block for all. For example:
catch (Throwable e) {
throw new CommandExecutorException(e);
}
many catch blocks one for each Exception. For example:
} catch (ClassCastException e1) {
...
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}
The first approach is very compact but basically groups every exception in the same case, it's useful only in the situation where all the exceptions are managed equally and do the same thing.
This approach is generally discouraged as it gives no control on the exceptions being catched, leading sometimes to tough bugs, which are also hard to find.
The second approach requires more lines of code but you can execute different operations depending on the exception occurred. This approach is more flexible but in some cases leads your methods to be very long due to exception handling.

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.

Java - make custom runtime error not dump trace

I have a kludgey use of Java RuntimeError in which I fully handle the error. Only problem is it gives me annoying trace telling me where the runtime error that I derived and threw occurred. How to suppress this trace?
For reference, the issue is I subclassed a non-throwing class and needed my subclass to throw. It was either "rewrite my program to read like a C program" or "use runtime error to bypass throw specification requirement." Obviously I'm finding the throw spec requirement very counterproductive right now - other workarounds that don't involve maintaining a bunch of "workIsDone" variables would be appreciated.
Without code it's awfully hard to know what you're talking about, but in general, stack traces come from a handler catching an exceptions and calling printStackTrace() on it. The stack trace doesn't appear unless something asks for it. Now, if an exception makes it all the way to the top of (for example) the AWT event thread stack, then the default handler will print it out this way.
As a rule, you want to handle exceptions. It can be a fine strategy to use runtime exceptions to get around the fact that some superclass method doesn't declare any exceptions, but then you take responsibility for always catching those exceptions. If you can't -- i.e., if some other code is going to catch them instead -- then this is a bad strategy and you can't use it.

Should I factor out error reporting in catch statements by re-throwing errors?

I have an error/exception that is thrown by a particular method. Any time this error occurs, I want to log it. Would it be good practice to log the error within the initial method, and then re-throw it? That way I would not need to log it in the catch statements of any function that calls this method.
It would look something like this:
public void doSomething() throws Exception{
try{
someFunction(); // throws Exception
} catch (Exception e){
logger.fatal(e.getMessage()); // always log this Excpetion
throw e;
}
}
My concern was the re-throwing of exact same error. I have not seen this done, and I wondered if it would be considered bad practice.
EDIT: I should add that this Exception should never ever happen. That might help understand this situation.
I would log information describing why your method is about to throw an exception rather than the exception itself. Let clients decide if they want to log the exception itself or handle it.
If you handle the exception I'm not sure it is the right thing to always log it. Depends on your application of course but in general it seems to me like it should be up to the client code to log the exception.
Thus, my recommendation, if the method throws the exception, let the client take care of the handling, even if it most often means logging it. (Unless of course you want the logging to be a documented side effect of the method.)
It really depends on your logging preferences. For example you database access layer may have a method that takes a SQL query as a String as an argument and executes it in the DB. Now you may want to log any SQLException in that layer and then wrap the SQLException by a custom exception [like a DatabaseException] and then re-throw it back to the parent layer. You may also want to encapsulate some additional behaviour like a boolean shouldRetry in your DatabaseException object so that the parent layer may retry the operation again. Logging the SQLException right away will let you debug the issue more easily later.
EDIT:
This approach makes more sense when your parent layer does an operation that might throw more than one kind of exception. For example, in the above scenario, the method that takes the SQL query might also throw a InvalidHostException if the database manager is unreachable or a ConnectionRefusedException, if the database manager refused connection due to overload. In such a case you might log the exception and then wrap it with the more general DatabaseException. Also if the method threw a ConnectionRefusedException then you might want to set the shouldRetry variable to true; while the same will be false for a InvalidHostException. This allows the caller API to try to call the method again after sometime if the value of shouldRetry was set to true.
NOTE: Except SQLException, the rest are creations of my imagination. :-)
I would log the error in the initial method only if there was pertinent information there that would not be available in the client code.
Maybe you could use aspect approach. So after each busines method you check the exception type that has been thrown and verify whether it matches criteria of exception that should be logged. If so you log it and rethrow exception otherwise you just rethrow exception without logging. This allow you to centralize your error logging and disable/enable it when necessary apart from business logic - this is typical cross-cutting concern not core concern.
public class MyLoggerInterceptor ... {
#AroundInvoke
public Object invoke(InvocationContext ic){
try{
ic.proceed();
}catch(Exception e){
if(exceptionShouldBeLogged(e)){
logger.fatal(e);
}
throw e;
}
}
}
There are already a lot of answers but I would say that you need to make the best decision with the information you have at the time, but you then need to monitor what you are logging when your application runs. (many developers don't do this, me included)
If you think your logging is to verbose change it and if you find that trying to investigate an issue you don't have enough information then you add more logging in.
Its like method naming, its difficult to get right the first time but keep changing until you get it perfect.

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.

Categories