Is this sort of Java exception style bad practice? - java

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.

Related

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.

Java structure - Is there ever a need to nest try statements?

I have just been thinking about this, as it is possible but I want to know if it is considered "bad practice". I believe it is, but I want to ask for views on it to check my opinion.
Is it bad to do something like this:
try{
something();
somethingelse();
try{
foo();
bar();
}catch(Exception e){
e.printStackTrace();
}
somethingelseagain();
}catch(Exception e){
e.printStackTrace();
}
I think there should never be a need to do this, since anything that throws an exception would trigger the first catch anyway.
Views are greatly appreciated.
In your example, as written, the inner catch is a bit redundant.
However, nested catches would have more use in circumstances such as:
catching different exceptions
doing something different in the handler block for the two catches
inner catch might catch the exception, do something, then re-throw the same exception which the out catch block could catch
Also, don't forget the potential use of the finally block, which can execute cleanup code even if an exception was caught.
You should generally try to catch the most explicitly typed (i.e. specific) exception(s) as possible.
The subject of exceptions is an interesting one, and not without controversy.
A case that I think you might want to nest try statements is if you request user input in your catch and that input might be invalid.
Nested try-catch is fully justified when circumstances call for it. For example, you don't want to skip any steps and break out of the main try if a certain method throws a certain exception. If it throws any other exception, then you want the normal behavior.

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.

How to identify which function call threw a particular exception in a try block?

Let's say there are three consecutive function calls in one try block and all of them throw the same type of exception. How can i figure out which function call threw the caught exception when handling it?
You can put a try-catch block around every single method call.
Or you take a look at the exception stack trace. Their is described which line of code throwed the exception.
getStackTrace()[0].getMethodName()
EDIT:
Throwable
StackTraceElement
like this:
try {
function1();
} catch (Exception e){
// function1 error
}
try {
function2();
} catch (Exception e){
// function2 error
}
try {
function3();
} catch (Exception e){
// function3 error
}
old method: have three try/catch blocks
new method (since 1.4): Throwable.getStackTrace()[0]
So I'm guessing that something about your code makes the obvious solutions tricky, perhaps the method call sites are a level or two down, or not at the same level? What exactly prevents you from just keeping a counter?
In any case, you need to either count invocations, use multiple try blocks, or do that and define your own exception which contains the missing information (and the old exception, because it's a subclass) and then rethrow it.
Perhaps you could subclass the object with the exception-throwing method, in order to wrap the method call and implement the counter?
I think introspecting the stack trace to do error handling will hurt you very badly later. If you need separate actions for separate lines, then have them in individual try-catch blocks.
You may also just want to have a simple variable keeping state, so you can check on the value, to determine how far you got. I think that will work much better.
int state = 0;
try {
step1();
state = 1;
step2();
state = 2;
....
} catch (Exception e) {
if (state == 2) ....
}
Edit: Downvoters, please notice I started saying this is a bad idea ;-)

Throwing exceptions in Java

I have a question about throwing exceptions in Java, a kind of misunderstanding from my side, as it seems, which I would like to clarify for myself.
I have been reading that the two basic ways of handling exception code are:
1.) throwing an exception in a try-block with "throw new ...", and catching it immediately in a catch-block - the so called try-throw-catch mechanism.
2.) throwing an exception in a method with "throw new ..." and then declaring in the header of the method that this method might throw an exception with "throws ..." - the so called pass-the-buck.
I have recently read that "it doesn't make any sense to throw an exception and then catch it in the same method", which made me think whether I understand the thing in the wrong way, or the person who had written this had something else in mind. Doesn't the first way of handling exceptions does exactly this (the try-throw-catch mechanism) ? I mean, it throws an exception and catches it in the same method. I have read that it is a better practice to throw an exception in one method, and catch it in another method, but this is just one (probably better) way. The other way is also legal and correct, isn't it?
Would you, please, give me a comment on this ? Thank you very much.
Exceptions should be thrown from a method when that method is incapable of resolving the exception on its own.
For example, a FileNotFoundException is thrown from new FileInputStream(new File(filename)) because the FileInputStream itself can't handle a case where a file is missing; that exception needs to get thrown so the end-user application can handle the problem.
There are some cases where exceptions could be handled within a method. For example, a Document model method throwing a BadLocationException could be handled within a sufficiently intelligent method. Depending on the problem, either the exception can be handled or re-thrown.
(Anyway, I'd argue that throwing an exception from within a try-catch block so the catch block can be executed represents really bad logic flow)
I think you misunderstood the first case. Normally you add a try-catch-block when you call some method which may throw exceptions. Catching locally thrown exceptions indeed doesn't make much sense. In particular you shouldn't use exceptions to exit from loops, as this is extremely slow compared to a standard approach.
Doesn't the first way of handling
exceptions does exactly this (the
try-throw-catch mechanism)? I mean, it
throws an exception and catches it in
the same method.
That's not a "way of handling exceptions" - it's utter nonsense. The whole point of exceptions is to let another method up the call stack handle it. If you're going to handle the condition within the same method, there's no point in using an exception - that's what if() is for! If that makes the control flow of your method too complicated, you should probably refactor some of the logic into separate methods - and then it might make sense to have those throw exception that the remaining method body catches.
That being said, I can imagine one special case where it could make sense to throw and catch an exception in the same method: when you're already calling a method that may throw an exception and have a catch block to handle it, then in some cases it could make sense to throw an exception to indicate a similar problem that the existing catch block can handle in the same way.
The person who wrote "it doesn't make any sense to throw an exception and then catch it in the same method" is entitled to their opinion, but it's not widely shared. There are plenty of cases where throwing and catching an exception in the same method is what's needed. The simplest is where you are doing a sequence of operations and the failure of any one of them makes the rest invalid. If you detect that one of these operations fails it's perfectly reasonable to throw an exception and catch it at the end of the method. In fact it's the logical way of doing things. Arguably you could rewrite the code to not use the exception, maybe with some status flags and a break statement or two, but why would you? Using an exception makes it clear what's going on and improves code readability.
I'm gonna answer your questions in turn, then add some comments to the end. I'm not an authority on exception handling, but I hope my comments are helpful.
"Doesn't the first way of handling exceptions does exactly this"?
My answer is yes, as you describe it the first method does operate by throwing and catching an exception in the same method. However, I don't know that try-throw-catch has to work as you describe it.
"I have read that it is a better practice to throw an exception in one method, and catch it in another method, but this is just one (probably better) way. The other way is also legal and correct, isn't it?"
I agree that catching exceptions from a second method is better, but the first way is legal. Is it correct? well that's for you to decide, it is your code, after all.
For the most part, I agree that it doesn't make sense to throw an exception then immediately catch that exception in the same method. If we do this because the method is particularly long/complex and handling the error using other logic would complicate things more, then I would suggest moving some of this logic to another method and calling that method and catching its exception.
If our code is simpler, then it may be easy to handle the error using code that doesn't consist of throwing an exception.
My comments:
The try-throw-catch mechanism you mentioned may not need the exception to be thrown in the same method. I would have to read the text you found to be certain, but I would expect that it isn't necessary. If it didn't need the exception to be thrown in the same method, then your exceptions handling strategy is a combination of 1) and 2).
In the combo, one method would use try-throw-catch mechanism to catch an exception thrown by a called method. It seems to me that 1) and 2) should work together to form your exception handling strategy.
Now, maybe someone will come along and give us some wonderful reasons why we might want to throw an exception in the same method. I expect there are some, but to me they seem the exceptions, not the rule.
Cheers,
Ed
With the first way do you mean something like this:
try {
ok = doSomething();
if (!ok) {
throw new Exception("Error");
}
ok = doSomethingElse();
}catch (Exception e) {
}
This will allow you to exit the try-catch block without executing the rest of it. This is the only valid usage I can think of throwing an exception with throw and catching it yourself in a try-catch block. However, standard if blocks should be used instead. I don't understand why someone should throw an exception and then catch it himself.
The second way is more standard, especially if the caller of the method that throws an exception is an external module. This is a way of signaling that something real wrong happened. It is the responsibility of the caller to handle the exception.
If you're going to manually throw an exception, then obviously you know there has been some error that needs to be handled. Rather than throw the new exception, then catch it, then immediately handle the error, why not just handle the error? You (and the processor) don't need to go through all the work of generating an exception and catching it. The exception also makes the code harder to read and debug.
You would throw an exception, rather than just handling the error immediately, if:
Other code, like the code that called your method, should handle the error. For example, if your code is not UI code, then it probably shouldn't generate windows. This is your method #2.
You can take advantage of the try, catch, finally block. It's possible that you could write cleaner code this way, but I think that 90% of the time your code would be more readable using simple if statements.
My expierence is that using the first method gets your code quickly unreadable - since the functionality and the error-handling is getting mixed up. BUT it makes sense in some cases where you have a try{}catch{}finaly{} - for example in file handling or database handling where you ALLWAYS want the connection to be closed.
try{ //do something
}catch(Exception ex){
//log
}finally{
//connection.close
}
For everything else I use the second option - just for the reason to centralize my error-handling routines and keep the readability of the code implementing the businesslogic itself.
In my opinion, try blocks that you write should not include any "throw new" that are caught inside the same method. When you throw an exception, you're saying "I've encountered a situation that I can't handle; somebody else will have to deal with it." Your method with the "throw new" should either create an unchecked exception to throw or declare a checked exception in its method signature.
If you're using 3rd party classes that may throw exceptions, your method should have a try/catch block if you can actually handle the situation if an exception arises. Otherwise, you should defer to another class that can.
I don't create my own exception and then catch it in the same method.
Using an exception for control flow is specifically dealt with in Effective Java, 2nd Edition by Joshua Bloch, Item 57:
Item 57: Use exceptions only for exceptional conditions
...exceptions are, as their name implies, to be used only for exceptional conditions; they should never be used for ordinary control flow. [italics mine]
So while it certainly "works" to use exceptions to control flow, it is not recommended.
The reason why that would seem as nonsense ( throwing and catching in the same method ) is because that would be an scenario of using exceptions for flow control. If you already have enough data as to identify the condition where the exception should be thrown then you could use that information to use a condition instead.
See below:
1) Throwing and catching exception in same method ( wrong )
public void method() {
try {
workA...
workA...
workA...
workA...
if( conditionIvalid() && notEnoughWhatever() && isWrongMoment() ) {
throw new IllegalStateException("No the rigth time" );
}
workB...
workB...
workB...
workB...
} catch( IllegalStateException iee ) {
System.out.println( "Skiped workB...");
}
workC....
workC....
workC....
workC....
}
In this scenario the exception throwing are used to skip the section "workB".
This would be better done like this:
2) Using condition to control flow ( right )
public void method() {
workA...
workA...
workA...
workA...
if( !(conditionIvalid() && notEnoughWhatever() && isWrongMoment() ) ) {
//throw new IllegalStateException("No the rigth time" );
workB...
workB...
workB...
workB...
}
workC....
workC....
workC....
workC....
}
And then you can refactor the condition:
if( !(conditionIvalid() && notEnoughWhatever() && isWrongMoment() ) ) {
for
if( canProceedWithWorkB() ) {
implemented as:
boolean canProceedWithWorkB() {
return !(conditionIvalid() && notEnoughWhatever() && isWrongMoment() );
}

Categories