Catch and logging for irrelevant operations - java

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.

Related

Is there such thing as 'too much cleanup' when handling thread interrupts?

This great article about best practices for handling interrupts mentions the following:
Sometimes it is necessary to do some amount of cleanup before propagating the exception. In this case, you can catch InterruptedException, perform the cleanup, and then rethrow the exception.
He then goes on to give an example of a method that catches InterruptedException, does a couple lines of cleanup, and then propagates the exception onward.
His small example makes perfect sense, but let's say I have a much longer interruptible method, whose task is not so simple, and it must be performed atomically. In other words, the amount of 'cleanup' it would need to perform when interrupted is substantial. Is this acceptable? If so, could I be cheeky and just catch the interrupt, perform all of the method's normal workflow (pretend it's 'cleanup'), and then propagate the interrupt at the very end?
In other words, I get that it's important to properly handle and propagate interrupts; my question is, how important is it to handle interrupts in a timely manner, and what counts as 'timely'?
Here's the example (real world) scenario where I'm coming from: I have a thread listening to a message queue; handling each message involves multiple HTTP calls and expensive DB operations, and, as currently (unfortunately) designed, these operations must all be performed atomically. Can I define my thread's interrupt-handling behavior to be: 'when interrupted, finish everything you're doing as normal before propagating the interrupt', or is this stretching the definition of 'cleanup' a little too much?
I don't think there is any useful notion of "too little" or "too much" cleanup. Certainly there is no general way to decide that you have done too little or too much.
Specifically ...
Can I define my thread's interrupt-handling behavior to be: 'when interrupted, finish everything you're doing as normal before propagating the interrupt', or is this stretching the definition of 'cleanup' a little too much?
There's no definite answer to this. If it makes sense (e.g. this behaviour is required), then it would be correct to do that. Whether you call it "cleanup" or not is irrelevant.
On the other hand, one of the common use-cases of Java interrupts is to signal to some part of the application to stop what ever it is doing because, for example:
the server is shutting down, or
the requested action is taking too long, or
the client that made the request has "gone away", and there is no other reason to complete the request.
In such cases, "finish everything as normal" may be the wrong strategy, especially if that is going to be expensive. (Or it may be the right strategy; for example, if there is no reliable way to back out of the sequence of actions that need to be done atomically.)
In short ... we can't tell you whether this is the right thing to do.
In other words, I get that it's important to properly handle and propagate interrupts; my question is, how important is it to handle interrupts in a timely manner, and what counts as 'timely'?
Again. These are questions that only make sense (and can only be answered) in the context of your application. It depends ...
But I don't think that this (cleanup) is restricted to interrupts. Consider the example in the article:
public class PlayerMatcher {
private PlayerSource players;
public PlayerMatcher(PlayerSource players) {
this.players = players;
}
public void matchPlayers() throws InterruptedException {
Player playerOne, playerTwo;
try {
while (true) {
playerOne = playerTwo = null;
// Wait for two players to arrive and start a new game
playerOne = players.waitForPlayer(); // could throw IE
playerTwo = players.waitForPlayer(); // could throw IE
startNewGame(playerOne, playerTwo);
}
}
catch (InterruptedException e) {
// If we got one player and were interrupted, put that player back
if (playerOne != null)
players.addFirst(playerOne);
// Then propagate the exception
throw e;
}
}
}
What happens (for example) if waitForPlayers or startNewGame could throw some other exception (checked or unchecked)? In that case, you could end up with lost players ... just like if you had an InterruptedException.
My point ... is that if you are concerned about making the code resilient in general (or "atomic") then it would be better to use a finally block to do the recovery; e.g.
finally {
// Make sure that we *always* put the players back
if (playerOne != null)
players.addFirst(playerOne);
if (playerTwo != null)
players.addFirst(playerTwo);
}
And if you need to do atomic operations that also entail changing state outside of the JVM and/or "the application" ... then even finally is not enough. There are some situations where code in a finally block won't be executed; e.g. if the JVM crashes or is terminated by System.exit(). (This is #EJP's point ...)
The approach you describe is sometimes referred to as "entering 'lame duck' mode", wherein you'll finish what you've already started but won't accept or initiate any new work.
It's fine as long as you document it, so that callers know what to expect. Encountering an InterruptedException means that some upstream caller wants to terminate the thread's activity, but safety trumps responsiveness. If you believe that these operations must all complete together (to the best of your ability), and stopping the unit of work with only part of it done would violate some requirement, then you are in your right to adhere to those requirements and put them above the implied requirement for timely cooperation with an interruption request.
Ideally, you'd cease any further progress with the transaction and attempt to roll back what you've already completed. However, there's subtlety in that design; you could be far enough along that just finishing the transaction would be faster than rolling back your nearly-complete accomplishments.
Again, the key here is documentation. If you document the behavior and find that your callers complain, then you have to push back on the competing requirement for transactional atomicity.
The end of that same article discusses "noncancelable tasks", which finish what they're doing (even if it may take a long time) before responding to the interruption. It sounds like that's what you have.
You don't necessarily have to abort what you're doing immediately, but you should set a flag to remember that an interrupt was requested, then re-throw the InterruptedException later when the atomic work is done.
No. What if you get interrupted again? If you need a method to be atomic you have much bigger problems than propagating exceptions.

Is it okay to handle Runtime exceptions?

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

It is normally if method throws a large number of exceptions?

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);
}

use catch throwable or catch Exception in new thread of execution

I need to find out best-practice for try-catch when launching a new thread.
Personally, I prefer Option 2.
Which option is the best-practice? Are there any factors that might make either option a best practice in some situations and not others?
Option 1
public void run(){
try{
//do something
}catch(Exception e){
// log
}
}
Option 2
public void run(){
try{
//do something
}catch(Throwable t){
// log
}
}
EDIT: Assume that you are writing the code that has to meet a stringent code review.
EDIT 2: I know the difference between the above two options. I am just curious about what is seen as '100% correct' by others.
I would use setDefaultUncaughtExceptionHandler(...) on the thread to catch what the runnable does not handle properly, but when it comes to the runnable itself, it really depends on what it has to achieve and to reasonably anticipate considering a reasonable execution context.
On the other side, creating a separate thread to execute a runnable is not a good strategy IMHO, FutureTask deals with these issues better.
In a root exception handler that simply logs whatever went wrong, distinguishing between Error and Exception is pointless, so catching Throwable is perfectly acceptable.
If instead you were writing some retry logic, I'd catch Exception, since there really is no point retrying after an Error - in fact, it could be dangerous, because the error was thrown in code that was not exception safe, and thus might have left the system in an inconsistent state.
Therefore, it depends on what kind of exception handler you are writing.
It is never advisable to catch Throwable since this includes errors that cannot be handled or avoided such as out of memory error and so on. Thus it is generally much better to catch Exception and not catch Throwable. Sometimes it is unavoidable such as when calling invoke method or other reflection methods.
What you are trying to ask about is the concept of a fault barrier and the correct way to implement one should be a standard defined by the project you are working on or the framework you are using.
If your project has a policy to log all exceptions/errors and not let anything print to standard error, you might want to look into using an UncaughtExceptionHandler.
A general best practice would be to catch only instances of RuntimeException.
public void run(){
try{
//do something
}catch(RuntimeException e){
// log
}
}
Catching Exception is too general because the Java language requires programs to deal with checked exceptions. By catching even checked exceptions at your fault barrier you are allowing the code in the //do something block to be sloppy and not handle checked exceptions.
Catching Error or Throwable is also generally considered a bad practice since an Error typically indicates that the JVM is in a state where it can not continue to function meaningfully.
Here is a good (and somewhat relevant) article on exception handling: http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html

How would you intercept all Exceptions?

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.

Categories

Resources