Best practice for Java exception handling - java

I wrote the following code recently; it uses a lot of exception handling. I think it makes the code look very unreadable. I could shorten the code by catching generic exception, such as
catch (Exception e){
e.printStackTrace();
}
but I also heard that catching generic exception is not a good coding practice.
public class DataAnalyzerTester {
/**
* #param args args[0] stores the filename
* #exception NoSuchElementException if user attempts to access empty list element
* #exception ArithmeticException if user attempts to divide by 0
* #exception ArrayIndexOutOfBoundsException if user supplied less than 3 arguments
* #exception IOException problems with creating and writing files
* #exception RuntimeException if user attempts to pass empty list to constructor
*/
public static void main(String[] args) {
try{
//some code
} catch (NoSuchElementException e) {
System.out.println("Accessing element that does not exist: " + e.toString());
} catch (ArithmeticException e) {
System.out.println("Division by zero: " + e.toString());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Please supply a command line arguement that specifies your file path: " + e.toString());
} catch (IOException e) {
System.out.println("Other IO errors: " + e.toString());
} catch (RuntimeException e) {
System.out.println(e.toString());
}
}
}
I would like to know if there is any better and cleaner way to catch multiple exceptions.

First, unless you have very good reason, never catch RuntimeException, Exception or Throwable. These will catch most anything that is thrown, and Throwable will catch everything, even those things you're not meant to catch, like OutOfMemoryError.
Second, avoid catching runtime exceptions unless it directly impedes with the critical operation of your program. (But seriously, if anyone sees you catch a NullPointerException, they are within their full rights to call you out on it.) The only exceptions you should be bothering with are those that you are required to handle. Out of your list of exceptions, the only one you should bother with is IOException. The rest are the result of not enough tests, or sloppy coding; those shouldn't occur in the normal run time of your application.
Third, in Java 7, you have the ability to do a multi-catch statement for your exceptions, if the exceptions are mutually exclusive. The example linked does a good job of explaining it, but if you were to encounter code that threw both an IOException and an SQLException, you could handle it like this:
try {
// Dodgy database code here
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
This cleans things up a bit, as you don't have unwieldy and huge chains of exceptions to catch.

First of all the problem with "best practice" advice is that it tends to over-simplify the question and the answer. Then someone (like yourself) comes along and notices that it is contradictory1.
IMO, best practice is to take "best practice" advice and people who regularly use that phrase with a healthy level of suspicion. Try to understand the real issues yourself, and reach your own conclusions ... rather than just relying someone else to tell you what is "best practice".
1 - Or worse ... they don't notice the contradictions, edge-cases, etc, and blindly follow the so-called "best practice". And occasionally, they find themselves in a dark place, because the "best practice" recommendation was inappropriate.
So what's the problem here? It is this statement:
but I also heard that catching generic exception is not a good coding practice.
In fact, it is not normally good coding practice to catch generic exceptions like Exception. But it is the right thing to do in some circumstances. And your example is one where it is appropriate.
Why?
Well lets look a case where catching Exception is a bad idea:
public void doSomething(...) {
try {
doSomethingElse(...);
} catch (Exception ex) {
// log it ... and continue
}
}
Why is that a bad idea? Because that catch is going to catch and handle unexpected exceptions; i.e. exceptions that you (the developer) did not think were possible, or that you did not even consider. That's OK ... but then the code logs the exception, and continues running as if nothing happened.
That's the real problem ... attempting to recover from an unexpected exception.
The (so-called) "best practice" advice to "never catch generic exceptions" deals with the issue, but in a crude way that doesn't deal with the edge cases. One of the edge cases is that catching (and logging) a generic exception is OK if you then immediately shut the application down ... like you are doing.
public void main(...) {
try {
// ...
} catch (Exception ex) {
// log exception
System.err.println("Fatal error; see log file");
System.exit(1);
}
}
Now contrast that with the (supposedly) good practice version in your question. What is the difference?
Your version produces more user friendly / less alarming diagnostics ... up to a point.
Your version is significantly more code.
Your version is unhelpful to someone trying to diagnose the problem because the stacktraces are not recorded.
And the counterpoints to 1 and 2 are:
You can spend limitless time honing the "user friendly" diagnostics for an application, and still fail to help the kind of user who can't or won't understand ...
It also depends on who the typical user is.
As you can see, this is far more nuanced than "catching generic exceptions is bad practice".

Related

Catching exception and throwing the same?

Could you please tell me which approach is better in below two code blocks?
catch (MyException e) {
throw new MyException ("Error processing request", e);
}
Or
catch (MyException e) {
throw e;
}
In order to compare two approaches, they should do the same thing. These two do not do the same thing.
The first approach would be better because you would change its message to a more user friendly one. Perhaps you could also log it (stacktrace or whatever...) before rethrowing it.
The second approach is better regarding performance. Actually, it would be even better if you did not catch the exception at all and let it throw it self.
You have to choose what is preferable, based on user experience and perhaps logging or performance. By default (and not always) I would choose the first.
Hope I helped!
I do not see point in catching the exception and throwing it again. Once rare scenario could be that you need to perform some operation when the exception has occurred but at the same time report the exception to the caller to take appropriate action.
If this is the case then, first approach is better because you are just throwing the same exception again (instead of creating a new once). Btw, both the approaches will preserve the stack trace, just the case is that first one will avoid creation of unnecessary object.
Eg:
catch (MyException e) {
// May be perform some clean-up activity and throw
throw new MyException ("Error processing request", e);
}
Preserve the inner exception, and I don't have an issue. Although, I don't think it makes sense to catch and then rethrow like that. Surely it would be better to just throw a custom-made exception?
What ever the case you can keep StackTrace, there is no issue. But it should be meanning full,there is no point catch and throw same Exception.
You can wrap the original exception like in your first option if you want to include any additional useful information for calling methods.
The first one, because the second approach (rethrow the same exception without any processing) is useless.
Typically you need to define exception processing at start of project. Will you use checked or unchecked exceptions? Will you use standard or your custom exceptions? How will you use exception inheritance? Where will you process (log) exceptions? What are information to pass in exceptions. Once you answear such questions, then it is time to start building your API.

Less try / More catch

I need to know if doing less Try and doing more Catchs is a good way to control a flux what is very important in exception control terms.
Because in the flux this should never go on if there's something goes wrong!
i'm not trying to save code lines, i need something visually easy to understand and functionally in code terms
Var ix;
Var iy;
Var iz;
try {
try {
do something ix;
} catch (Exception ex1) {
ex1.printStackTrace();
}
try {
do something iy;
} catch (Exception ex2) {
ex2.printStackTrace();
}
do something iz;
} catch (Exception ex3) {
ex3.printStackTrace();
}
OR
Var ix;
Var iy;
Var iz;
try {
do something ix;
do something iy;
do something iz;
} catch (Exception ex1) {
ex1.printStackTrace();
} catch (Exception ex2) {
ex2.printStackTrace();
} catch (Exception ex3) {
ex3.printStackTrace();
}
Those two examples will actually behave differently. In the second, if an exception is caught then none of the following do something will run. In the first they can each fail independently.
Always catch exception in as small and limited scope as possible; using too broad catches like
} catch (Exception ex) {
// wrong. use explicit exceptions,
// e.g. catch(NullPointerException ex) instead, possibly with multicatch
or catches on too big scope
try {
//... tons of code
} catch (IOException ex) {
// and the exception happened WHERE?
}
is an anti-pattern by itself.
This thing said, all that other people said is correct. The codes will behave differently, because nested catches actually handle the exception encountered within and not propagate it outside.
Multiple catches on e.g. Exception (replace with e.g. NullPointerException and the idea is still there) done in this fashion
try {
try {
// some code
} catch (Exception ex1) { /* stack dump or whatever */ }
} catch (Exception ex2) { /* stack dump or whatever */ }
won't work good too, because inner Exception is a valid catch for every exception of a given kind (in this case - every exception at all) - thus nothing catchable will propagate outside of it to the outer try/catch block.
Another thing (already stated countless times too) is that you should either cure the exception, throw it up (propagate) or die with the exception. Simply doing a stack dump is like saying 'you, my dear sir, have cancer'. It doesn't improve the situation for anybody. If you can't help it, propagate it. If nothing can handle it, die with some grace (stack dump is hardly a gracious way for a thread to die...).
And yet another thing to distinguish is Java's Throwable types, i.e. error vs checked/unchecked exception difference. In general:
Error should cause the thread to die immediately, because it signifies a serious VM/hardware error,
unchecked exception (RuntimeException comes to mind) is a really exceptional case, impossible or very hard to predict, so it should usually NOT be contained and rather just signaled to the user with programatic fallback to last validly executed code branch,
checked exception is a common exceptional case, which, in turn, MUST be handled by the programmer explicitly and shouldn't disrupt program execution.
tl;dr - please learn the rationale about using exceptions before actually using them.
Further reading: http://docs.oracle.com/javase/tutorial/essential/exceptions/ and http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683 (Item 39: Use exceptions only for exceptional conditions, Item 40: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors, Item 41: Avoid unnecessary use of checked exceptions, Item 43: Throw exceptions appropriate to the abstraction. )
The two ways are logically different. In the first way, you will try to do action "iy" even if action "ix" throws an exception. In the second way, if action "ix" throws an exception, then "iy" and "iz" will never be executed.
I would say it depends on what you want. Are any of your exceptions recoverable? Do you want to keep going after encountering an exception? These kind of things determine how you handle exceptions. Or at least, how I do.
This is very different !
In your first code :
If ix triggers ex1, it will continue to iy. But if it triggers ex3,
everything will stop.
If iy triggers ex2, it will continue to iz. But if it triggers ex3, everything will stop.
In your second code :
if an exception is thrown, everything will stop.
You should read this tutorial.
There is no single, correct answer to your question. It depends. As you can see from other answers your first and second code differs how in execution (some operations might be skipped in second example).
You should focus on:
type of exceptions you are catching (are those exceptions different, do you want to handle them differently?),
how you are going to handle the exception,
is one exception affecting other pieces of your code,
are two or more exceptions going to be catch by single catch statement,
etc.
You should consider each solution for given circumstances.

Subclassing Exception in Java: when isn't a custom message "good enough"?

This is more of best practice question.
I'm working with old Java code at the moment. I'm seeing a lot of subclasses of Exception only overwrite the constructors. I'm not sure if there is any practical use of subclassing Exception like this. I think just calling the Exception constructor and pass in a message would be just as effective, and there wouldn't be many subclasses around. Code is liability.
The point of subclassing is that your code can distinguish different types of failure and treat them differently. If you just change the message, then a human can distinguish them in the logs, but that's all.
If the exceptions you are seeing are not actually handled differently, but just caught in a catch-all catch(Exception e) then perhaps someone was being over-enthusiastic with the subclasses, but it is often useful for cleanly separating layers of code and working out which classes should handle which kinds of problem.
For example, one type of exception may indicate a timeout, and it may be appropriate to retry after a short delay, whereas another type of exception indicates an unrecoverable failure (an invalid query, perhaps) which must be thrown up to a higher level or perhaps indicated to the user.
To add to the other answers:
If you extend Exception and throw it, you're declaring a new checked exception. It will have to be declared on the throws clause of your method. You are saying to the caller: "Here is a unusual case which you must code for".
I think checked exceptions are over-used. They are only really useful in situations where the caller can expect to recover from the problem. The vast majority of exceptions I have seen are the kind that the caller cannot reasonably expect to recover from. In this case you should use a RuntimeException descendant such as IllegalStateException or IllegalArgumentException and let top-level error handling take care of it.
This is done to allow more cleaner and more precise catching of exceptions. If all of your code just throws Exception, your exception-handling code will have to look like this:
try {
// ...
throw new Exception("configuration error");
// ...
throw new Exception("missing value error");
// etc.
} catch (Exception e) {
// do something
}
And it will be awkward at the least to handle different kinds of errors in different ways. More importantly, this code will swallow all exceptions, even ones you weren't expecting and for which you haven't written specific error-handling logic. On the other hand, if you write
try {
// ...
throw new ConfigurationException();
// ...
throw new MissingValueException();
// etc.
} catch (ConfigurationException e) {
System.err.println("error: bad configuration");
System.exit(1);
} catch (MissingValueException e) {
return DEFAULT_VALUE;
}
you'll be able to easily and cleanly handle different kinds of errors, and won't have to worry that your error handling code will be run in situations that you didn't expect it to.
When you have a subclass, you can catch it. You can't catch an exception selectively depending on its message.
Subclasses are more descriptive and easier to use:
throw new Exception("User does not exist " + userName);
compared to:
throw new UserNotExistsException(userName);
also the latter exception can have getUserName() method and field accordingly to extract important information when caught. You don't want to parse exception message, don't you?
Subclassing is the way to go. later in the lifetime of the application you may have to change the exception message. Who knows it may be displayed on a page and the wording needs to be adjusted.
Wrapping the error message in its own Exception subclass helps maintain a clean code and easily test against a given error category.

Common / centralized method to handle multiple exceptions

This is on Java 6
Can I have a common method to handle my exceptions - so instead of doing this n times in each method
try {
// Do something
} catch (XException e) {
// Do something
} catch (YException e) {
// Do something
} catch (ZException e) {
// Do something
}
I have
try {
// Do something
} catch (Exception e) {
handleAll (e);
}
and method handleAll(e) does
if e.instanceOf(XException)
else if e.instanceOf(YException)
else if e.instanceOf(ZException)
Is there anything wrong with the 2nd approach?
Update:
My original question was about "centralizing the handling" in one place for both checked and runtime exceptions. The answers have pointed out I should avoid instanceof().
#aioobe's idea looks very neat to me. Are there any negative opinions on that approach?
There is one minor problem as I see it. Since you really want the handleAll method to rethrow any uncaught exception, it has to be declared throws Exception. This means that so does the methods that call handleAll.
If X-, Y- and ZException are all RuntimeExceptions I see nothing wrong with this. (I may have overlooked something though, as this is the first time I've seen this approach.)
To be sure that the instanceof approach behaves exactly as the catch clauses would, I would consider designing the handleAll(RuntimeException e) like this though:
private void handleAll(RuntimeException e) {
try {
throw e;
} catch (XException xe) {
...
} catch (YException xe) {
...
} catch (ZException xe) {
...
}
}
It's a BAD approach. It will reduce LOC (Line Of Code) but it will create difficult to understand, More resource dependent (It requires more memory and processing capacity). it also reduce Readability.
So first one is the best one
You can do this, but I don't think it's good coding style. It's convenient to keep exception handlers close to the lines that throw the Exceptions.
Suppose your code changes, and throws a new Exception. Then you have to update the method that handles them; so now you have to make changes in two places. Same happens if a particular Exception is no longer thrown by the code, or if you decide that some Exceptions should be handled at a higher level.
Also, I'm wary of "catch (Exception exc)". It's too general, try to make your Exception handlers as specific as possible.
Java 7 will make things better. Because catching multiple exceptions is possible.
There is something really wrong with the second approach: if the called method signature is modified and throws a new kind of exception, the code will still compile fine, whereas you have not handled this new exception correctly.
Using the first approach, the compiler will produce an error, which will force you to handle the new exception.
The second approach will catch all Exceptions, including RunTimeExceptions. Make sure you handle them correctly.
I think every exception is unique (when compararized place in code, not the time when exception is thrown) so you should not generilaze exception handling.
You might want to handle exception little difference each time IE. if some where is thrown FileNotFoundException you might create a new file but other time that might be fatal Exception that causes applications termination.

Is this sort of Java exception style bad practice?

Is it considered bad practice to have multiple try's in one method and structure the code like this?
public void whatever() {
try {
methodThatMayThrowIOException();
} catch(IOException io) {
// do something with exception here
}
// do more stuff here that won't throw exceptions
try {
methodThatMayThrowCustomException();
} catch(CustomException ce) {
// do something with custom exception here
}
}
If the method can continue execution, without any problems even if the specified exception occurs this should be fine.
In the event where the exception should cause problems further down the line in the method, I would have it bubble up.
No it's not. It is a good point to catch specific exceptions when they might be thrown, imho it is surely better than this:
public void whatever {
try {
methodThatMayThrowIOException();
// do more stuff here that won't throw exceptions
methodThatMayThrowCustomException();
} catch(ParentException e) {
// do something with custom exception here
}
}
Your code reads like it does because you want to do part 1 (and resolve, catching IOException if necessary), do the no-exceptions part, and then do the methodThatMayThrowCustomException. Your code can literally not be written any other way and retain the same functionality. That's an exaggeration, but any other version would be different in a superficial sense.
This is not the same:
public void whatever {
try {
methodThatMayThrowIOException();
// do more stuff here that won't throw exceptions
methodThatMayThrowCustomException();
} catch(IOException io) {
// do something with io exception here
} catch(CustomException ce) {
// do something with custom exception here
}
}
and the way it would execute if any of the Exceptions are thrown is quite different. If you need to sequentially recover from Part 1, hit Part 2 in any case, then carry on to Part 3, you cannot really write your code any other way.
There's nothing wrong with having two catch blocks, though mixing something that causes an IOException with something that throws a CustomException might suggest a mixing of concerns, making your code hard to understand. But as it is, it's not just valid, it's the only way to do what you're doing.
Looks OK but it depends on what methodThatMayThrowIOException and methodThatMayThrowCustomException do and whether failure of the first one (methodThatMayThrowIOException) should fail the whole whatever method.
It really depends on what you plan to do if an IOException thrown. Your style allows you to do more things, but if you're not actually planning to take advantage of that, then that intention is made much clearer by using the standard idiom.
public void whatever {
try {
methodThatMayThrowIOException();
// do more stuff here that won't throw exceptions
methodThatMayThrowCustomException();
} catch(IOException io) {
// do something with io exception here
} catch(CustomException ce) {
// do something with custom exception here
}
}
Here you can tell quickly that if IOException is thrown, then you only do what's inside the catch block and not much else.
I don't see why that would be bad practice, as long as you actually do something useful with the exceptions you caught.
There is no problem with this, AFAICS. However, 2 try-catch in a method stabs in my eyes. If you feel the same, I suggest you to refactor it in a proper way.
No. That's a pretty good practice to narrow down the scope where some kind of exceptions are thrown. I did this a lot in my code.
However, if you are sure that in one try...catch block, certain kind of Exception will only be thrown by a unique function, putting them in the same try block is also OK.
well it depends on what you are trying to accomplish. you would normally enclose a block of code in a single try-catch block if the code block should be executed as a block or not at all if some exception occurs. if it's not the case, then i believe it is much better to isolate the different code blocks throwing different exceptions into different try-catch blocks sandwitching "do more stuff here that does not throw exception". just a thought!
Personally, I think it looks cluttered. I prefer to have just one try, with as many catch blocks as I need. I don't care or multiple try/catch sequences in a single method.

Categories