This question already has answers here:
Try-catch: is this acceptable practice?
(8 answers)
Why are empty catch blocks a bad idea? [closed]
(20 answers)
Closed 9 years ago.
Say I have a try statement with and empty catch is that bad practice? For example say I have 2 try separate trys where it is possible for one to fail but the other to succeed or both succeed or any possible combination of such. Is that bad practice to handle code like that?
Example
if( mode == Modes.EDIT ){
try {user = userBo.findById(id).get(0); }
catch(Exception e) { }
try{
result = this.initializeEntityById(accountDao, id);
if( !result.equals(SUCCESS) ){
return result;
}
}
catch(Exception e){ }
}
In this example the variable in concern is 'id' where I'm not sure if the value coming in is valid and on the front end it doesn't really matter because the code handles whatever comes in and provides correct display.
So the question really is:
Is this a bad practice with the empty catch's?
Is there any potential instability that could occur that I'm not realizing?
Is there a better way to achieve what I'm looking to get at?
Yes it's always bad practice since you have no idea what went wrong where. You should at least log the exception.
The instability is that when something goes wrong, you have no idea what is wrong with your code.
It's never desirable to use exceptions for control-flow. The performance is atrocious, and exceptions should only be used for exceptional circumstances. Here's what you can do:
Make the exception part of the method signature and let a higher level handle it.
Catch the exception, but wrap it in a semantically-appropriate exception and rethrow it so a higher level can handle it.
Handle it. This can also be done in multiple ways:
Don't let the exception happen: instead of catching the exception, perform an inspection on the data to see if it can cause an exception. For example, in your case I think you should have a method like userBo.existsWithId(id) which will return a boolean that says whether the user exists. Or have the findById return null if the user cannot be found, and check to see if user == null. I think this is your best bet.
Recover from the exception in some sane way (depends on your business logic).
This is bad practice.
There's no instability, per se, but with empty catches, nothing is being done about the exception, which could leave an object in an inconsistent state if some aspects didn't get processed due to the exception.
With that said, empty catch blocks make for very difficult debugging. Even in production code, you should include a basic "notification" for most exceptions.
In testing code, use e.printStackTrace( in every catch block that does nothing otherwise.
1) Is this a bad practice with the empty catch's?
Yes this is not a good practice.
2) Is there any potential instability that could occur that I'm not realizing?
If you anything goes wrong and any exception thrown then you will not be able to identify what goes wrong because in catch block you are not doing anything so it is assumed to be handled.
3) Is there a better way to achieve what I'm looking to get at?'
Try to log the exception stacktrace in catch block . or throw it again
e.g. e.printstacktrace();
Yes, this is bad practice.
If an exception is thrown, it should be handled somehow, and the catch block is meant to hold the handling code. At the very least, if you don't need recovery code and alternate logic in your method to handle a caught exception (which would be rare), you should log the exception so you know it happened.
You can read an excellent article on handling exceptions here:
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=2
I found the second page to be especially helpful.
Related
This question already has answers here:
Why Re-throw Exceptions?
(13 answers)
Closed 9 years ago.
In some legacy code I see this, that an overbroad exception is being caught, and then thrown again, Is this a good practice? Does throw e; rethrow the same exception, or create a new one ?
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
System.out.println(sb.toString());
throw e;
}
throw e is rethrowing the same exception. At least it preserves the original stacktrace. It's just writing a message to stdout recording some information about what happened, then letting the original exception proceed on its way.
It's not a great practice, it should be enough to log the exceptions in a central place, recording their stacktraces. If you need to add more information (as in the example, where it logs an id), it's better to nest the original exception in a new exception as the cause, then throw the new exception. I would guess this probably occurs in contexts where there is no centralized logging or where exceptions tend to get eaten somewhere.
This is usually a bad practice. catch(Exception e) (sometimes called Pokemon Exception Handling for when you gotta catch 'em all) catches every single exception. Such exception handling is rarely useful because:
It catches runtime exception too.
You lose information about the type of exception that was thrown.
You cannot react to or handle specific exceptions.
Your method signature now is public void whatever() throws Exception, which is rarely useful. Now everything further up the chain has no idea what kind of exception you have thrown; they will have to do instanceof checks which defeats the purpose of catching specific-exceptions entirely.
As far as your second exception is concerned, throw e; throws the same exception object. If you wanted to wrap the exception, you can create a new one, which means you would do something like throw new MyCustomException(e);. You would also need to change your method signature.
If there is nothing further up the chain, I guess this isn't as bad (still isn't great, though). It looks like a method that is trying to log all exceptions that are thrown. However, again, there are better ways of doing this.
throw e does throw the same exception. There might have been reasons for doing this, but there is also a reason not to. In your example code, a message is sent to System.out, but if a stack trace were printed later on System.err, it won't be syncronized, and in fact the two might end up interwoven in your console.
A better approach would be the following:
catch (Exception e) {
StringBuilder sb = new StringBuilder(
"Oops. Something went wrong with id: ");
sb.append(id);
sb.append(". Exception is: ");
sb.append(e.toString());
throw new Exception(sb.toString(), e); // The original exception is an argument
}
This will create a new Exception with the modified message, and append the original Exception to the stack trace to help with debugging.
My best guess would be it is trying to have two layers of protection. Making sure that an error message is displayed and also asking the client to handle the exception the way it wants to because the catch clause is not doing anything to recover from the exception.
I won't consider it good/bad practice. Depending on your requirements you can consider to go either way like there might be 100 of different clients using your API and each one of them has a different way of recovering from an exception. By displaying what went wrong it is adding a default action layer just below the layer where client decides on how it will handle the exception.
Now back to your question. I think throw e throws the same exception object. As exceptions are objects in java you need to create a new exception object before you can throw it which I can't see happening in your code.
It can be a good practice. I think I always use conversion to RuntimeExceptions during prototyping. After this if there is a need one can change this into better exception handling. For this my purpose there is an utility class in Guava called Throwables which makes exception propagation.
In your case however the exception should be converted into a runtime exception, because declaring a method throwing a general Exception is just the same as a method throwing RuntimeException for the calling party. In the first case it 'catches everything', in the latter it 'catches anything'. I have not yet experienced the difference between two of these in real-world applications. So I prefer RuntimeExceptions as they require less typing.
Catching Exception
Checked exceptions (IO exceptions, security errors, concurrency, etc)
Runtime exceptions (anything, unpredicted garbage, see below)
Everything - these are 99% of all errors (there are Errors left however)
Catching RuntimeException
null pointer exceptions, index out of bounds exceptions, access exceptions, + API which wraps propagates exceptions into RuntimeException - this is ALSO A LOT
My point is after when you're catching an Exception you can't really handle all these cases. So it makes no difference except for the less typing for the calling party if you wrap it into a RuntimeException.
This question already has answers here:
Why can you not throw and catch an Object in Java? [duplicate]
(5 answers)
Closed 9 years ago.
why below code is not working ? whereas every class is extended from Object class.
try {
// simple code , throw some exception
} catch (Object e) {
// handle the exception
}
If Exception class is inherited from object class than why Object reference is not allowed in catch block ?
If anyone knows answer of the above question than please let me know.
The argument to a catch clause must inherit from Throwable
This constraint was put into the Java language from the start and is part of the promise to JRE writers that they can leverage in case it helps them make things go faster.
From the javadocs:
The Throwable class is the superclass of all errors and exceptions in
the Java language. Only objects that are instances of this class (or
one of its subclasses) are thrown by the Java Virtual Machine or can
be thrown by the Java throw statement. Similarly, only this class or
one of its subclasses can be the argument type in a catch clause. For
the purposes of compile-time checking of exceptions, Throwable and any
subclass of Throwable that is not also a subclass of either
RuntimeException or Error are regarded as checked exceptions.
Read more here: http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html
If Object where accept on the catch clause, something like this would actually work:
try {
if (needToThrow) {
List<String> messages = new ArrayList<String>();
list.add("a nice message");
list.add("another message");
list.add("random message");
throw messages;
} else {
//do other stuff here
}
} catch (List list) {
System.out.println("Got a list of messages, lets handle them");
}
Yet that would be a very strange way to control the execution flow, something that a simple if statement would solve.
So, the try and catch mechanism is not for doing basic flow control, but handling unexpected results. When a part of the code hits an unexpected result, it throws a message indicating that he cannot continue, he will abort the next statement and return the execution to the scope above. Hes basically saying I received an error and cannot continue, someone handle this situation. For someone to deal with this situation, resources needs to be gathered: the JVM will make a snapshot of the whole stack and put it inside a Throwable object. Thats why you can only catch something that is a Throwable. Also the above example would perform poorly as error resources would be gathered where it is not necessary.
On the two known Throwable types
Situations where the program can recover from are classified as Exceptions, like trying to open a missing file, connecting to somewhere that is not reachable, trying to access a wrong URL and so on.
When the program cannot recover, those situations are classified as Errors, like running out of memory or running into a compiling error.
Although you could still write your own class that inherits from Throwable, the two above types already cover all the possible error types (being recoverable or being not recoverable), so you probably wont see anything being catch that are not from any of those.
Also, catching a Throwable is a bad practice (Can you handle something that cannot be handled like Errors?). When you want to "catch anything in my code", catch Exception
You seems new to programming. Anyways, Object is the root of java class hierarchy and from that hierarchy Throwable hierarchy is defined whose descendants are used to throw or get thrown itself if there is a related problem.
Basically what you need to learn is only errors and exceptions can be used in catch block because we track the problem occurred not the object that cause the problem.
So if u get ArrayOutOfBoundsException(which is derived from Exception& Exception is derived from Throwable) that means an array object is the reason for this Exception and better exception handling involves catching of specific problem.
I assume i helped you , if it really helped then hit my answer as acceptable.
I have a method throws an Exception
public int myMethod throws Exception
I have another function calls myMethod function and hava try-catch block.
I throws a runtime exception to enforce the program to be terminated.
Is this a proper way to terminate the program? If I do this way, it prints the stack trace twice and the stack trace from RuntimeException is useless.
What is the suggested way to terminate program in catch clause with printing the full stack trace.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
throw new RuntimeException();
}
}
The answer is "it depends".
If this code is part of the application itself then calling System.exit(int) is possibly the best option. (But if the application is "failing", then you should call exit with a non-zero return code. Zero conventionally means "succeeded".)
However, if there is a significant possibility that this code is going to be embedded / reused in a larger Java application, calling System.exit(...) is problematic. For instance a library that calls System.exit(...) when something bad happens is going to cause havoc for an application that uses it.
For something like that, you might throw a custom runtime exception which you catch and handle specifically in your main method. (If I was doing that, I'd pass the Exception as a constructor parameter to the custom exception ... and make it the cause exception. And I wouldn't print it / log it at that point.)
(Calling System.exit(...) also causes problems when you are unit testing ... 'cos the call will most likely pull the plug on the JVM running the test suite!)
The other point is that catch (Exception ...) is almost always a BAD IDEA. The point is that this catches just about everything (including all sorts of things that you never dreamed could happen!) and buries them. It is far better to catch the specific exceptions you are expecting (e.g. checked exceptions) and can deal with ... and just let the rest propagate in the normal way.
If you are stuck with catch (Exception ...) because you are using something that is declared as throwing Exception, the best way to deal with it is to change the throws Exception. And the sooner the better. Change the throws Exception to declare a list of (more) specific exceptions that you expect to be thrown by the method.
public int callMyMethod(){
try{
myMethod();
}
catch(Exception ex){
ex.printStackTrace(System.out);
System.exit(0); // terminates with exit code 0, no extra stack trace.
}
}
Exception handling is one of the most important aspects in programming.
The answer for your question depends on what type of application you are working on.
system.exit(0) will just terminate your program and this can create a lot of havoc .
Also make sure that you never catch Exception , if you are doing that then you are catching all the types of exceptions which you may not intend to handle also.
Always catch Specific exception such that it gives you opportunity to handle it in a manner which you need.
I recently got to know that using try and catch blocks for NullPointerExceptions is a bad practice.
If so, then I have following questions:
Why is this a bad practice?
What are the alternatives to catching a NullPointerException?
When you add a try/catch block around a section of code which you expect to throw a NPE under specific circumstances, you might inadvertently forget about another object used by that code which might also be null and cause one. When you then add the code to react on the expected NPE in the catch block, the code will also be executed on the unexpected NPE. This will output a misleading error message at best and result in completely unexpected program behavior at worst.
An example:
try {
ThingamabobFactory.getInstance().createThingamabob(ThingamabobFactory.getDefaults()).thingamabobify();
} catch(NullPointerException e) {
// so... which of the above method calls did return null?
// ...or was the NPE even thrown INSIDE one of these methods??
}
So when you expect that an object will be null in some situations and you want to handle this case, do so by checking if (object == null) to avoid any false-positives.
The big problem with catching NullPointerException is knowing what to do about it, because it can have so many possible causes.
You can be more sure you know what was null and why if you specifically test for null. For example, suppose a block of code contains a call to a method that returns null under specified circumstances, and you want to take some action if it does so. If you test the method result immediately, you know the null is due to the circumstances that cause the method to return null.
On the other hand, if you wrap the block in a try-catch and catch the NullPointerException, maybe the method returned null, but you cannot be sure that is what happened. Something else may have gone wrong in the try block, causing the exception.
You should avoid having any exceptions if possible since producing them and sending them through app is expensive in resources.
null point is easy to handle , just check to see if something is null or not
You can avoid to treated directly by using throws, or you can try an alternative method by using BCEL.
either wrapped illegal argument exception when you are at transliterate service side , or just handled predictable null case to work on preconditions of a model or method, or catch exception , inside this catch, if instance Of ... to write log or more.
generally, never directly catch null point exception, it is run time exception, it has logic:
if you know where will be null in your code , then handle it. if you don't know, the, after you catch , what you do? you are not JVM , right?
We have received Java code from a software supplier. It contains a lot of try-catch blocks with nothing in the catch part. They're all over the place. Example:
try {
spaceBlock.enable(LindsayModel);
} catch (Exception e) {
}
My questions are: Is the above acceptable practice? If so, when? Or should I just go ahead and remove all of these "bogus" try and catch statements?
To me this looks like terrible practice, but I'm not experienced enough in Java to tell for sure. Why catch errors if you're not going to do anything with them? Seems to me, you would only do that if you were confident that an exception would be of absolutely no consequence and you don't care if one occurs. However, this is not really the case in our particular application.
EDIT To give some context: We bought a Java-scriptable product from the supplier. Alongside the product, they provided a large proof-of-concept script tailored to our needs. This script came "free of charge" (though we wouldn't have bought the product if it hadn't come with the script) and it "works". But the script is a real pain to build upon, due to many things that even I as a Java novice recognise as awful practice, one instance being this bogus try-catch business.
This is indeed terrible practice. Especially the catching of Exception rather than something specific gives off a horrible smell - even a NullPointerException will be swallowed. Even if it is assured that a particular thrown exception is of no real consequence, one should always log it at the very least:
try {
// code
}
catch (MyInconsequentialException mie) {
// tune level for this logger in logging config file if this is too spammy
MY_LOGGER.warning("Caught an inconsequential exception.", mie);
}
However it is unlikely an exception is completely meaningless in this situation. I recommend researching exactly what exception(s) the application's code is intending to swallow here, and what they would really mean for the execution.
One important distinction is whether the try/catches are used to swallow checked exceptions. If this is the case, it probably indicates extreme apathy on the programmer's part - somebody just wanted his/her code to compile. At the least, the code should be amended:
try {
// code
}
catch (SpecificCheckedException sce) {
// make sure there is exception logging done farther up
throw new RuntimeException(sce);
}
This will rethrow the exception wrapped in an unchecked RuntimeException, effectively allowing the code to compile. Even this can be considered a bandaid however - best practice for checked exceptions is to handle them on an individual basis, either in the current method or farther up by adding throws SpecificCheckedException to the method signature.
As #Tom Hawtin mentioned, new Error(sce) can be used instead of new RuntimeException(sce) in order to circumvent any additional Exception catches farther up, which makes sense for something that isn't expected to be thrown.
If the try/catch is not being used to swallow checked exceptions, it is equally dangerous and should simply be removed.
Terrible, indeed. Swallowing an exception like this can be dangerous. How will you know if something bad has happened?
I'd feel better if the vendor wrote comments to document and acknowledge it ("We know what we're doing"). I'd feel even better if there was a strategy apparent in the code to deal with the consequences. Wrap it in a RuntimeException and rethrow; set the return value to an appropriate value. Anything!
"All over the place"? Are there multiple try/catch blocks littering the code? Personally, I don't like that idiom. I prefer one per method.
Maybe you should find a new vendor or write your own.
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
}
This looks like unfinished code. If the enable method throws an Exception then it will be caught and swallowed by the code. If it doesn't then it does not make sense to try to catch a non occuring exception.
Check to see the methods and where their signatures are not followed by throws exceptionName, then remove the empty try-catch statements from the places they are called.
You can theoretically put try-catch around any statement. The compiler will not complain about it. It does not make sense though, since this way one may hide real exceptions.
You can see this as a sign of bad code quality. You should probably be prepared to run into problems of different type too.
It's not the best:
It hides evidence of the exception so debugging is harder
It may cause features to fail silently
It suggests that the author might actually have wanted to handle the exception but never got around to it
So, there may be cases where this is OK, such as an exception that really is of no consequence (the case that comes to mind is Python's mkdirs, which throws an exception if the directory already exists), but usually, it's not so great.
Unfortunately you cannot just remove it, because it the try block throws a checked exception then it will have to be declared in the throws clause of the method. The callers of the method will then have to catch it (but not if the callers also have this catch (Exception e) {} abomination).
As an alternative, consider replacing it with
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
Since RuntimeException (and classes that extend it) are unchecked exceptions they do not need to be declared in the throws clause.
What did your contract with the supplier specify? If what they wrote, bad practice and all, meets the spec then they will charge you for a rewrite.
Better to specify a set of tests that will enter many or all of those try-catch blocks and hence fail. If the tests fail you have a better argument to make them fix their terrible code.
Horrible idea on the face of it, totally depends on what you're actually calling. Usually it's done out of laziness or habituated bad practices.
Actually ... not so fast.
There are legitimate cases for ignoring an exception.
Suppose that an exception has happened already, and we're already in a catch(). While in the catch(), we want to make best effort to clean up (which could fail, too). Which exception to return?? The original one, of course. The code looks like this:
try {
something-that-throws();
} catch(Exception e) {
try {
something-else-that-throws();
} catch(Exception e1) {}
throw e;
}
When we really don't care whether an operation succeeds, but (unfortunately) the operation's author throws an exception if a failure occurs.
if (reinitialize) {
try {
FileUtils.forceDelete(sandboxFile); // delete directory if it's there
} catch(Exception e) {}
}
The above saves a rather tortured attempt to see if sandboxFile actually exists before deleting it anyway.