I have following code example:
private boolean openThroughCommPort(IProgressMonitor monitor, int portNum)
throws InterruptedException, PortInUseException, IOException,
UnsupportedCommOperationException, TooManyListenersException,
UnsupportedVehicleException, InnerCanceledException {
...
}
I don't sure that it is good way - throws many many exceptions in method signature.
Maybe you can tell me best practies for this case?
First of all if a method throws that many exceptions it means that the method is doing too many things. You should think of distributing the work to separate methods.
Secondly if it is important for the caller (the caller is at same abstraction level) to know which exact exception occurred and take particular actions on it then it makes more sense to throw individual exceptions and not wrap it. Also the point made by #Jon Skeet is true that it will also reduce possibility of effective documentation.
If the caller does not need to know the exact cause, if the abstraction level is different then it would make sense to wrap the exception in your own custom exception which is inline with the caller's abstraction level.
Do not wrap or swallow the InterruptedException, or your application will behave incorrectly in a threaded context. Just a couple of links for reference, be sure to handle it in a proper way:
http://www.ibm.com/developerworks/java/library/j-jtp05236/
Java Thread Sleep and Interrupted Exception
Calling methods should deal with exceptions or let them flow up. You can add a short description on method's Javadoc.
It is always better to handle specific exceptions rather than generalizing it. There is nothing wrong in throwing so many exceptions. This would better help in documenting things also.
I would recommend to create your own wrapper Exception and use try/catch in your method.
Narendra Pathai is completely right that you should only do that if the caller does not need to decide who to proceed based on which exception was originally thrown.
You can wrap your exceptions like that:
try{
//do something
} catch(Exception e){
throw new WrapperException(e);
}
Related
One of the projects I inherited is riddled with tons of try/catch blocks catching the general Exception. I've been slowly but surely refactoring this, but there are so many, such that I have been contemplating bringing this up as a concern in a meeting. This got me to thinking...Is there ever really a case where catching the general exception is justified in a production environment? I could not think of a case where I NEEDED to catch the general exception, but I'm also a fairly recent grad and I'm sure there's tons that I don't know. I did a little research, and I can find lot's of reasons why NOT to catch the general exception, but nothing concrete on when this practice is justified. Obviously if you're calling a method that already throws Exception you have to catch it. But is there ever a reason some method could throw Exception and it should not be refactored to throw the specific exception.?
Throw Exception only if you need to throw Exception, specifically. If you throw too-general an exception, you are effectively just shouting "there is a problem", without giving specific information as to what that problem is.
Catch Exception only if Exception is thrown, specifically. If you catch too general an exception, you're losing the opportunity to handle specific exceptions in the correct way.
Throwing Exception is the equivalent of returning Object instead of a more-specific type which would be useful to the caller; catching Exception is the equivalent of assigning a return value to an Object variable, rather than a more specific type that you could do useful things with. Basically: you are discarding available type information.
Sometimes you have to throw Exception, because you are writing a general framework. For example, Callable.call throws Exception, because you don't know what code will be executed there, so allowing it to throw Exception means that you don't constrain users of the class. And consequently, if you're calling a Callable, you need to catch Exception; but you need to do it with care.
The vast majority of people aren't (or shouldn't be) writing frameworks, and so you shouldn't be throwing or catching Exception.
There is good advice on this in Effective Java, Item 61, " Throw exceptions appropriate to the abstraction" (this is the number in 2nd Ed; don't know about 3rd Ed). Basically: you almost certainly don't want to throw Exception, but you might want to throw IOException rather than FileNotFoundException, if the fact that you're reading from a file isn't relevant to your API.
Catching general Exception isn't best practice, because if you are catching exception you are telling that you can handle it and recover from that exception state, but if you can't recover then it might be better to fail than to keep working with very unpredictable state.
Another thing that can happen is to catch exception that is supposed to be handled at higher level which can again lead to dangerous state.
There is possibility that code was written before Java 7 when multi-catch was introduced so they used Exception instead of writing each separately, or that developer wasn't familiar with this.
Only case in which catching Exception is justified, in my opinion at least, is at top of the application(main) - catch all exceptions that are not handled at lower levels, log them and exit for safety reasons, and crash nicely and show reasonable message to end user.
This brings us to another thing, and that is throwing Exception, same as with catching one you shouldn't throw Exception, that is same like returning Object from every method, you lose identity.
If this two things are very common in project you are working on maybe you should consider mentioning that to senior developer.
I've a method to save timing information of each operation:
public void queueTimerInfo(long start, long end, String msg) {
try {
timer.queue(start, end, msg);
} catch (InterruptedException e) {
Logger.info(e.getMessage());
}
}
I call the above method after each operation. What matters is the operation itself, whereas the timing is just a secondary task. That's why I decided not to do anything when the method fails, except logging it.
But I was always told that logging without managing the exception is a bad practice. So how should I rewrite the above code?
If you know the consequences, i.e. the timer.queue() call might be interrupted and not queue the data, and you can live with that, then it is OK to ignore the Exception. As with most rules, you need to know when to break them.
However, I would document your decision with a comment in the catch block, so that whoever maintains the code later knows that not handling the Exception was not an oversight, but a deliberate decision.
But I was always told that logging without managing the exception is a bad practice
What does "managing" mean? Rethrowing them? Blindly following steps 1, 2, 3 because "zOMG an exception was thrown!!111"?
If you blindly follow best practices and other sorts of advice regardless of your context, then you'll probably end up with really problematic and awkward decisions. Don't do things just because it's best practice. Acknowledge the best practices, but at the same time make sure they actually make sense in your situation.
Ask yourself: does that exception make a difference? Does it break a contract? Does it change the flow of your application? Do you absolutely not want that to happen and if it does, then the situation is truly exceptional and you should really deal with it somehow?
If it doesn't make a difference and so on, then just logging it is perfectly acceptable. It really comes down to your context and to the significance of your exception.
LE: Of course, as Thomas suggests, you may want to document your decision.
InterruptedException is special because it does not signal an error.
When a method declares a InterruptedException it tells you that it is a blocking method which can be cancelled by interrupting its thread.
Brian Goetz explains:
When a method throws InterruptedException, it is telling you that if
the thread executing the method is interrupted, it will make an
attempt to stop what it is doing and return early and indicate its
early return by throwing InterruptedException. Well-behaved blocking
library methods should be responsive to interruption and throw
InterruptedException so they can be used within cancelable activities
without compromising responsiveness.
You should either
don't catch the exception and add a throws InterruptedException
catch it, do clean up and rethrow it
when you can't throw it (e.g. in a Runnable) call Thread.getCurrentThread().interrupt();
If you just swallow the exception you will compromise responsiveness of your application.
Can you wrap it and rethrow? And then your common exception handler can take care of logging and reporting. And provide context with it if possible.
It's generally a good practice to not handle runtime exceptions.
I have this scenario :
/**boolean returns false if the method execution fails,
so that an error can be shown to user*/
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}
catch(Exception e)
{
//Log the exception and return false
return false;
}
return true;
}
So from the Servlet calling it will get a boolean value. If it's false, we show a message 'Save Not sucessful'. Is this okay or is there a better way of doing it ?
Is it okay to handle Runtime exceptions?
As long as you can do something intelligent at that point, yes. This 'never catch run-time exceptions' is pure nonsense. You'll probably want to log them and do other things, as well.
It's generally a good practice to not handle runtime exceptions.
This sentence implies a false premise: the question is not whether, but when to catch runtime exceptions.
At some point in your code you should definitely have a "catch-all" exception handler. This point is called the exception barrier, and it is high enough in the call stack to encompass a complete unit of work (basically, the scope of one database transaction).
This should be your governing principle:
if an exception must cause the current unit of work to be aborted (rolled back), then do not catch that exception until the exception barrier;
if an exception is of local character only, and its appearance only means taking a different route to the handling of the request, then do catch and handle it early.
Note that the above doesn't use the fruitless checked/unchecked distinction. Most modern frameworks completely avoid checked exceptions and go out of their way to shield the programmer from such exceptions being thrown from lower-level code.
In practice, more than 90% of all exceptions are of the first, aborting kind. This is what is meant by the term "unrecoverable"—it means you can't continue what you are doing right now, but the server can stay up and process all other requests. I see many people confusing this with "the JVM is about to die", but exceptions which have that meaning are exceedingly rare and usually there is no special handling code for them.
Lastly, note that the "catch-all" handler should catch not only RuntimeExceptions but also Errors because you want every exception logged the same way. If you let an exception escape your application code, there is no knowing what behavior it will cause. Note that there are some common errors, like StackOverflow and OutOfMemory, which can in principle cause unrecoverable damage and therefore rightfully belong to the Error hierarchy, yet in most real-life cases do no damage beyond aborting the current request. You definitely do not want to shut down your service at the first sight of such an error.
No, catching a general Exception will mask any other problems you don't want to catch. Better catching specific exceptions making it harder for unexpected ones to go missing.
I guess your question has two aspects: 1) Handling RuntimeExceptionas the heading suggested and 2) handling generic Exception these are two different things.
The Javadoc of RuntimeExcepton list a bunch of its subclasses (NullPointerException..etc). If you look carefully, these are nothing but the programming errors and instead of handling them in catch block, should be corrected the the code itself so that they do not occur.
Handling generic Exception is generally referred as a poor practice and rightly so because it hides the specific exceptions which might need different handling.
But in case similar to yours, if there is a Servlet giving a call to method there has to be a graceful way to tell the user that there was some problem with the application while processing the request instead if showing the stacktrace.
So what you are doing could be one way of handling and as a good practice keep track of errors/exceptions in the log and correct any RuntimeExceptions
boolean returns false if the method execution fails,
so that an error can be shown to user
This is a clear reason for the method to throw an exception. It is why the exception mechanism exists in the first place. Best practice is to use exceptions for these types of circumstances, not boolean signals.
Anytime you follow this kind of pattern, you suffer in several ways
The caller cannot be sure what really happened. Was there a communication failure? Was the data corrupted? There is no way to tell when you return a simple "FAILED" signal.
Because the caller cannot know what happened, you take away options for the caller. Maybe the caller could do something in certain error cases.
You increase the potential for data errors. Again, since the caller cannot know why it failed, the caller may make assumptions about why it failed and continue in cases when the entire program should halt. If the program continues, it may decide to process invalid data when it really should stop.
I highly recommend reading the sections on exception handling in Effective Java. Basically, if you can't do anything meaningful with an Exception in your method, you should allow it to pass up the stack. In the worst case scenario, the API you reference throws a generic checked exception, giving you one of three choices (EDIT: Changed to void return type because the boolean return type no longer has any meaning -- you either succeed or throw an exception)
-Create your own.
// "MyFatalException" would be a checked Exception
public void saveData() throws MyFatalException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new MyFatalException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
}
-Throw an existing type (my preference is for subclasses of RuntimeException)
public void saveData() throws IllegalStateException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new IllegalStateException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
-Declare to throw a generic Exception and let it pass up (I do NOT recommend this, but you'll see many developers who do this)
public void saveData() throws Exception{
// no try/catch needed. Just make the call
}
The general concept is that frameworks or APIs would throw a RuntimeException only in situations when the error is not recoverable in code. e.g: your Db is down, or your server socket is down and things like that.
Though its not bad to catch such exceptions but whats actually thoughtful is what do you intend to do after catching them. e.g: people prefer to catch DB level connection problems and errors which are runtime exception subclasses and show error pages on their websites. Checked exceptions are usually for code level situational cases and catching them and handling is what code is expected to do.
In case you try something like this, since you don't want your users to error page you can do this, provided you caught all other exceptions before this.
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}catch(db_Connectivity_Exception e){
//exception like credentials invalid
}catch(db_table_Exception e){
//table desc. changed
}
catch(Exception e)
{
//Log the exception and return false
//Since you are going to log your error I hope is not harmfu
return false;
}
return true;
}
Still this is not best practice
What is according to you the simplest way to intercept all exceptions in a Java application?
Would AOP be needed to provide this kind of functionality or can it be done with dynamic proxies or is there another way?
Is the simplest solution also a good solution regarding impact on execution performance?
I would like to hear possible solutions from more experienced developers as I'm trying to grasp the technical know-how about the subject.
EDIT:
Thanks for the good advice already, but doesn't the current advice only apply to checked exceptions? What about unchecked exceptions, like NullPointerExceptions, wouldn't it be useful if these could be caught and that the application on catching them dumps the heap/stack to provide you with the current context of the application at the moment of crashing?
What is the purpose of you wanting to intercept every exception - for logging, error reporting?
Intercepting every single exception in every single line of a Java program is possible, but would probably incur quite a performance hit. If it's unavoidable, it'd probably be best to use something like AspectJ, which can run at compile-time (i.e. it "weaves" into your class files) and as such is much faster than dynamic proxies.
But it's something I would try to avoid doing at all costs! In general I would say it's better to limit the scope of the exceptions you want to catch. Also you might want to look into Thread.setDefaultUncaughtExceptionHandler, which I find useful for displaying error dialogs in GUI applications.
Similar to Phil's answer, here is some sample code showing how to use the uncaught exception handler. This works for both checked and unchecked exceptions.
Edit: Updated to print the stack trace based on updated comments in the question.
import java.lang.Thread.UncaughtExceptionHandler;
public class Test {
public static void main(String[] args) throws Exception {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
}}
);
// throw new RuntimeException(); /* this works too */
throw new Exception();
}
}
At Nate and Konamiman... What you're suggesting does not work at all and does not answer the OP's question.
What if the OP starts a new thread from inside your try/catch?
For example:
public static void main(String[] args) {
try {
final Thread t = new Thread( new Runnable() {
public void run() {
System.out.println( 3 / Math.min(0,4) );
}
} );
t.start();
catch(Throwable t) {
...
}
}
Then you're not catching the exception.
The correct way to do it is to use Thread.setDefaultUncaughtExceptionHandler.
public static void main(String[] args) {
try {
...
catch(Throwable t) {
...
}
}
More importantly than simply catching all exceptions is WHERE you catch the exception:
Don't catch an exception unless you can do something about it. If you can't do anything about it, either let it bubble up to the next level or catch it, re-wrap it as a more specific exception and re-throw it.
Always have a global exception handling block (like in Nate's answer) to catch any errors you can't handle anywhere so you can fail somewhat gracefully.
If you simply want to catch an Exception, a try/catch block will suffice. If you want to prevent them being thrown or do some logging or wrapping of the Exception, you will probably need some AOP to do this. AspectJ will handle it pretty well, but beware of potential performance bottlenecks.
Dynamic proxies will only work when the method is proxied, so if any Exception is thrown and caught inside the execution of the proxy object there is no means for the proxies to intercept the Exception.
One thing to consider is if you are catching all exceptions, or only checked exceptions. To catch all exceptions, AspectJ's around throwing or after throwing advice would weave some processing around every method, this involves the creation of JoinPoint objects and synthetic methods at every method invocation. This is not normally a problem unless the process is in a tight loop, where the garbage collection can go through the roof.
To all those questionning the need to catch all exceptions...
There are a lot of valid reasons to catch all exceptions:
someone mentionned displaying a dialog in a GUI app telling about the problem
working around bugs in a 3rd party API you really need
working around bugs in some JVM implementation
self-healing software.
automatic online exception reporting.
Note that Java itself does intercept all exceptions on the EDT (Event Dispatch Thread) and spawns a new EDT when the EDT dies. You can consider that a form of "self-healing" software. The EDT dying is not something unheard of and doesn't exactly prevent the applications from running correctly (on the contrary). (and, yup, Swing and AWT have quite some bugs, just take a look at the Sun bug parade ;)
It could be argued that any self-respecting software should actually take into account the case of an unforeseen exception (are all the software you ship 100% bug free and never gets new releases, bug-fix releases?) and do something smart when such unforeseen exception happen.
The 'something smart' may be preventing the software from crashing (like in the EDT case), warning the user, sending a report, etc.
Answers questionning the need to do such a thing or suggesting that doing so is a bad practice should IMHO be modded down.
In java there is a possibility of re-throwing the exception but there is any advantage in it?
One example of when you want to rethrow an exception is when you don't really know how to handle it yourself, but you'd like to log that the exception was thrown. Rethrowing it allows you to both capture the stack information that you need to log, and pass the exception up the call stack for the caller to handle.
Sure. If you need to perform some special processing (logging, clean up, etc) for the exception, but can't "handle" it completely, it is common to do the processing and then rethrow the exception. Note, that in many cases (especially cleaning up resources) you probably want a finally clause rather than a catch/rethrow.
Sometimes, you want a specific type of Exception to be thrown by a method, but there are rare instances that cause other Exceptions to be thrown within the method. I often wrap the causal Exception with my desired Exception and then rethrow the desired Exception.
This is really useful when you can't determine that the Exception has caused your operation to fail until control is passed to the calling method (or one of its ancestors), since if the process does eventually fail, I can trace back in the stacktrace to see why.
I haven't done Java in years, but from what I remember it's just like other languages with exceptions and OO. Exceptions can be subclassed, and often, you'll want to catch a base class of many exceptions, but might not be able to handle all of them. So say you're handling a remote file transfer, and want to catch all IOErrors, because you handle most of them, but not DiskFull. You can rethrow that, and let someone else deal with it further up the chain, but deal with the other issues, like TransmissionFailed, by re-doing the transmit.
If you can somehow justify that you need to re-throw the same exception that you caught, I'd argue that there is something wrong with your design.
Catching one exception and re-throwing another makes perfect sense. For instance, you may want to add detailed information that the original exception did not have.
Real World Cases
Here are some real world situations in which I needed to rethrow java exceptions:
When doing JDBC call, I would catch a SQLException. However, postgres would throw a PSQLException with additional data and status. In testing edge cases we were able to corrupt the database and we wanted the logger to have very specific data on the exception and state. We would wrap the original exception in a new exception with more data regarding the server state and rethrow.
When implementing a text parser, I would want to catch a number of runtime parsing exceptions such as NumberFormatException and pass them up the stack with additional data on what text caused and the source of the text that caused the parsing exception.
My coworker told me of a project in which he worked where every exception was wrapped in another exception of one of two types - RetryableException and FatalException. In the case of a Retryable exception, the application would wait and retry the operation after a fixed period of time. I'm not exactly sure about how I feel about this design, but I can see it as a stop-gap for dealing with some transactional issues.
In some cases I would be using an existing API that had a throws defined for a high-level exception and I would be doing an operation that would throw an unrelated exception (that I felt really belonged as a RuntimeException) - I then would rethrow the exception as the cause of the more general exception.
The most pure case that I can think of in which you may want to rethrow an exception is when you want to add additional data to it. For example:
public bizMethod() throws CoolBizLogicException {
int policyId = getPolicyId("bar");
try {
coolBizLogic(foobar); // this throws an exception
}
catch (CoolBizLogicException cble) {
cble.setPolicyId(policyId);
throw cble;
}
}
I don't think so. If you can't handle it, don't catch it.