Of course exceptions should be handled at the appropriate level you think and appropriately. Suppose you don't know what to do with checked exception and you wrap it in appropriate custom unchecked exception just to propagate up to the top level (it is supposed that you don't handle that wrapped exception and other possible unchecked exceptions at some medium level up apart the level which original exception occurred at (because of you don't want or don't know how)). Go further, All unhandled exceptions (unchecked and checked, that were wrapped in unchecked) reached the top level (main method, controller of webapp, etc); of course I should something to do. All I want to do is to notify the developer by using log entry that something was wrong and communicate the user that his request can't be serviced correctly (using different messages in dependence of what message is appropriate for that exception). To do that, I use in catch block RuntimeException (if it catches not custom unchecked exception, I’ll send the user a message "Serious problem occurred" or something like that; probability that such not custom unchecked exception will be cached greater than zero, and you must communicate about it). Some articles (first, second) advise not to catch instances of subclasses by super type in catch block (or it is only related to checked exceptions?). If I used accurate types of exceptions in catch blocks I would miss some unchecked exceptions and application would crash (and of course there would be duplicate code snippets in those catch blocks performing logging and notifying the user). As an example, I can provide the snippet that is constructed in jsp translation phase and uses super type to catch instances of subclasses of that supertype
// some code
try {
// body of translated JSP here...
} catch (Exception e) {
out.clear();
pageContext.handlePageException(e);
}
// some code
My question: is this concept is correct to use RuntimeException in catch block at the top level to report about all problems to developer and communicate the user about all occurred problems? Of course, exception handling in this case is reduced to just notifying developer and user that the problems occurred and there are no recovering strategies. Maybe it is hard to call that concept as exception handling. Please correct me and I appreciate any ideas about that concept.
I think in your situation this is the right way to go.
You don't want users at best to be confused by seeing a stack trace and at worst revealing possible security issues by seeing back-end server names, database credentials, database schema etc.
Your catch should hide this information from users and print a helpful error message to the user instead so at least they know what the problem is.
My only concern with your code is perhaps you should catch RuntimeException separately from Exception (or even Throwable)
try {
// body of translated JSP here...
}catch(RuntimeException re){
//something unexpected
//handle here
} catch (Exception e) {
//checked exception
//handle here
}
Wrapping all your Exceptions with a RuntimeException, and handling them in your main method, or wherever you define as being your top level, is a very bad practice. Instances of Exception should be handled as close as possible from where they were thrown, as they exist to identify an error from which you can recover. For instance, if you are trying to open a file, and get a FileNotFoundException, you should then take action on this (display an error message, add an entry in your error log, etc.).
Most of the time, RuntimeException represent programming errors (). More often than not, they indicate that the application is in an unstable state, and recovery is hard if not impossible. IllegalStateException, NullPointerException and IndexOutOfBoundsException are examples of such situations.
Now, the concept you are proposing, where all RuntimeExceptions are caught in the top-level method is not a viable solution for any software containing more than a few hundred lines of code, and a very bad practice in shorter programs.
Assume you have an application with 100k lines of code. Once an exception has been thrown, it will be impossible from your top-level method to correctly handle your exception. What should it do if it is a NullPointerException? Where was it thrown from? And what about that CloneNotSupportedException? You will end up having a top-level method dozens of pages long that will handle every possible exception, with the biggest if-then-else statement of all time.
Additionally, if you implement such a concept, you should be aware that whenever an exception is thrown, your application will go in that catch block in your top-level method. Once you have logged the error, you will never be able to return the control to the part of your application that generated the error, because you will not have the context from which the Exception was thrown.
Related
Why do we need try/catch blocks to catch any Exceptions that may arise in our code? Once we run the program and lets assume we have a RuntimeException, won't the program just automatically abort and give us the error anyways? Why do we need try/catch blocks to do this for us then?
It's just good practice. If the user is given with something like "IndexOutOfrangeexception" what is he going to do with it? Just assume everything is OK and he should start over? What in case of doing some work with the software - is the work lost? What happened?
Put yourself in such stuation: you downloaded some software, you start using it as normal, and you are happy with it. But one day you run program and it gives you error and program dies - do you know what happened? No. Do you know what went wrong? No. Do you know how to prevent it and start using software so the error doesn't occur again? No.
YOU ARE THE DEVELOPER, you know what happens inside. So for example, you are trying to save data in database, but somehow connection got lost and you will likely get an exception - in catch block you can catch this exception and give the user MEANINGFUL information, e.g. "The connection with database is lost. Check the network. Your data is not saved and you should do the work again." - isn't that better than just some "SQL exception" alongside with the stacktrace?
Additionally, catch/finally blocks are here to clean-up potential mess, for example you are writing some content to a file, but it only makes sense, when you can write all data, not just the part of it. So in catch block you could erase incomplete data, so the file is not corrupted for example.
Also, when working with unanaged resources, you should use finally block to clean them up (for example DB/netowrk connections).
Think about the scenarios when working with a live website or application. You wouldn't want the user to see a blank screen or a screen full of error trace code. In such scenarios, potential areas of exception can be handled to show a message to the user that makes sense "sorry, you are exceeding more than 10 items in your cart etc ", "you do not have sufficient amount in your account", "username cannot have symbols ", "out service us un-operational right now please come back later".
Try catch is used to handle the such error conditions gracefully. You can enclose a code set into try and its catch would be responsible to handle it. Handling may depend on your use case but your java program wont terminate.
Abrupt termination of program doesn't let you know the actual reason of failure.
Because if you don't catch an exception the entire method execution will simply stop, including the execution of any calling methods. So if a method A needs something of method B and calls it, and method B throws an exception, then that exception will cause method A to stop execution. If method A was being called by another method that method will stop execution too if it doesn't catch the exception from method B. So an exception will work its way up the method calling chain until it is catched by a method or gets to the most upper/outer method.
Also, any exception that is not inheriting from the RuntimeException class or is not an instance of the RuntimeException class itself must either be catched or else your code will not compile. If you really don't want to handle this kind of exception then you can also let the calling method receive the exception by adding throws Exception to your method signature. A runtimeexception extending class is called an unchecked exception, you don't have to include that in the method or in the method signature. Anything extending Exception but not RuntimeException is called a checked exception and should either be catched or put in the method signature by using throws keyword.
EDIT: Here you can find a good explanation too Does every exception have an required try-catch?
Other than examples users given, also, on Android for hardware specific operations, camera for instance, can throw RuntimeExceptions even you do everything right, it does it a lot with camera based on devices. I set ISO for instance camera and it's not a crucial for my app to work but i don't want my app to crash so i throw an exception and show a warning to user so app continue to work.
When I throw an exception from the package in which I handle the database, in the package in which I handle the UI, should I throw the same exception or create another?
The UI package should know the exceptions of the package which I handle the database?
We as programmers want to write quality code that solves problems. Unfortunately, exceptions come as side effects of our code. No one likes side effects, so we soon find our own ways to get around them. I have seen some smart programmers deal with exceptions the following way:
public void consumeAndForgetAllExceptions(){
try {
...some code that throws exceptions
} catch (Exception ex){
ex.printStacktrace();
}
}
What is wrong with the code above?
Once an exception is thrown, normal program execution is suspended and control is transferred to the catch block. The catch block catches the exception and just suppresses it. Execution of the program continues after the catch block, as if nothing had happened.
How about the following?
public void someMethod() throws Exception{
}
This method is a blank one; it does not have any code in it. How can a blank method throw exceptions? Java does not stop you from doing this. Recently, I came across similar code where the method was declared to throw exceptions, but there was no code that actually generated that exception. When I asked the programmer, he replied "I know, it is corrupting the API, but I am used to doing it and it works."
Please visit here for more details.
To keep your layers tightly coupled, I recommend to abstract your Exceptions (if there isn't a fitting standard exception). With abstract I mean that you could wrap database-dependent exceptions like SQLException into a PersistenceException or sth. like that. This way you can easily change your layers without having to worry about changing code of the layers above.
You should then only catch and handle the exception if you can handle them, e.g. propagate it to the user in you GUI. Otherwise you should throw them to the next caller, until it is handled on a higher level.
You should avoid recreating new exceptions on their way up, that wouldn't add any information in most cases.
You should throw an Exception that makes sense. More importantly you should not throw an exception that doesn't. Exceptions represent error states that you cannot easily recover from, meaning that if you have code to handle things like missing files, it should not throw an exception. You should only throw an exception when something unexpected happens.
As exceptions propagate up through your stack, they should be diversified, depending on what part of the code they where caught in.
For instance your persistence framework may throw an SqlException, your DAO Layer may re-throwthis as an IllegalArgumentExection, or ObjectNotFoundEception, your Service Layer may throw a MalformedRequestException, an AccessDeniedException or a DeviceNotEnrolledException. Lastly your UI may display this to the user in any number of meaningful ways.
I recommend putting the exceptions where it relates the most. You should have different exceptions that handle the code in different types of situations. The UI is going to have different types of exceptions it should handle than the database.
Use pre-defined exceptions where it makes sense, you could also make your own exceptions and put them in both packages if need be.
Design it so that the code can be handled in a way where the catch statement is easy to logically locate and the catch statement handles the code and can do some sort of recovery after being passed up the hierarchy.
The type of situation we are concerned with the most are checked exceptions. These are problems that we can anticipate and catch and try to make a recovery. Make sure you aren't using too many of these! They are costly to resources!
Is there a way I can automatically print a stack trace when Exception occurs? I understand I can do so by manually surrounding a block with a try-catch statement, but there's no prior-knowledge where an exception would happen in a program, and doing it in suspicious region block by block would be super inefficient, since there're potentially many. So is there any configuration option or any programmatic way to do so in Android?(like surrounding a try-catch block in the highest level of method?, but what's the highest level of method)
Define a global exception handler in your Application class and add any code you need to it.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
It is recommended that you still re-throw caught exceptions so that the app stops running, because it will be in an unstable state and not doing so can cause the app to freeze up.
catch (Exception e) {e.printStackTrace();}
The highest level is the Application level I believe. But in general just catch it at the usual activity lifecycle should be sufficient.
Extend Exception and do whatever you want in your custom Exception class.
There are two major kinds of exceptions:
Exceptions caused by programming errors (e.g. dereferencing a null reference, ...)
Exceptions caused by the environment (e.g. user enters 'abc' in a numeric field, network cable was unplugged, ...)
In most of the cases you can't really recover from the first ones. (If something unexpectedly went wrong, how can you know what to do to recover safely?) This are usually unchecked exceptions and you don't have to catch them somewhere.
Uncaught exceptions are catched by the system/framework and logged automatically!
Take care for the second type of exceptions! They are mostly not unchecked and have to be either cached or specified via throws clause. Handle them, probably log them, and try to recover if possible.
This document explains how you can read the error log and other logs on android devices. There are also apps available that can display the log on the device itself.
Also read this basic exception tutorial!
This is probably a broad question, not quite SO style, but I'd still like to get some hints or guidelines if possible.
I've been looking through some legacy code and found a part of it that has methods with exceptions nested 3 or 4 levels down.
Is this considered to be a normal practice or should one avoid such codestyle where possible? If it should be avoided, what are the negative effects besides the increasing costs of exception handling and decreasing readability? Are there common ways of refactoring the code to avoid this?
I personally prefer the following ideology
Wrap Alien Exceptions
An "alien" exception is an exception thrown by a Java API or a third party library. In other words, an exception you do not control.
Its better to catch all alien exceptions and wrap them in an appropriate application specific exception. Once the alien exception is converted to your own exception, you can propagate that exception any way you like.
Rethrowing Checked Exceptions can get Messy
If your application uses checked exceptions, rethrowing the original exception means that the method rethrowing it must also declare it.
The closer you get to the top of the call hierarchy, the more exceptions will be declared thrown. Unless you just declare all your methods to throw Exception. However, if you do so you might as well use unchecked exceptions, since you are not really getting any benefit from the compiler exception checking anyways.
This is why I prefer to catch non-application specific exceptions and wrap them in an application specific exception, before propagating them up the call stack.
Guidelines For Wrapping : The context in which an exception occurs may be just as important as the location of the exception itself. A given location in the application may be reachable via different execution paths, and the execution path may influence the severity and cause of the error, if it occurs.
If you need to add context information to an exception as you propagate it up the call stack, you need to use active propagation. In other words, you need to catch the exception in various relevant locations on the way up the call stack, and add the relevant context information to it, before rethrowing or wrapping it.
public void doSomething() throws SomeException{
try{
doSomethingThatCanThrowException();
} catch (SomeException e){
e.addContextInformation(“more info”);
throw e; //throw e, or wrap it – see next line.
//throw new WrappingException(e, “more information”);
} finally {
//clean up – close open resources etc.
}
}
Checked Exceptions should not be propagated up the stack or chained if possible. If a method is throwing a checked Exception its caller is supposed to handle it, if caller is not handling it and propagating it to its caller, then overall complexity increases.
In a three layered example : Dao , Service , Controller
DAO layer will throw DAOException
Service layer should not expose DAOException to Controller , instead it should be throwing relevant BuinessExceptions, which the Controller should be handling.
Exception handling tends to be an expensive way to handle flow control (certainly for C# and Java).
The runtime does quite a lot of work when an exception object is constructed - getting the stack trace together, figuring out where the exception is handled and more.
All this costs in memory and CPU resources that do not need to be expanded if flow control statements are used for flow control.
Additionally, there is a semantic issue. Exceptions are for exceptional situations, not for normal flow control. One should use exception handling for handling unanticipated/exceptional situations, not as normal program flow, because otherwise, an uncaught exception will tell you much less.
Apart from these two, there is the matter of others reading the code. Using exceptions in such a manner is not something most programmers will expect, so readability and how understandable your code is suffer. When one sees "Exception", one thinks - something bad happened, something that is not supposed to happen normally. So, using exceptions in this manner is just plain confusing.
Please take a look at below links
Exception Handling: Common Problems and Best Practice with Java 1.4 - pdf
Why not use exceptions as regular flow of control?
Best Practices for Exception Handling
Error Handling
Mr. Google Links
I've been looking through some legacy code and found a part of it that has methods with exceptions nested 3 or 4 levels down.
Is this considered to be a normal practice or should one avoid such codestyle where possible?
This is not a necessary process to handle your exception in this way, as it will increase your application overhead, until you really need to handle very specific exception(checked or Alien Exceptions) and you can ignore overhead to get specific information to handle that exception.
If it should be avoided, what are the negative effects besides the increasing costs of exception handling and decreasing readability?
As I mentioned you will not get specific information about the exception, if you are not going to use nested exception handling(throws with some added information to the upper handler) you may/may'not do specific action on behalf of some tough exception, but in nested case you can do action by handling that specific situation.
Are there common ways of refactoring the code to avoid this?
If you have a poorly factored program that does what the you want and has no serious bugs, for god sake leave it alone! When you need to fix a bug or add a feature, you Refactor Mercilessly the code that you encounter in your efforts. Override the Exception Class in your custom Exception Handler and add some added features to handle your problem.
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
Hop this will help you.
You should do away with the exception nesting. You should either avoid chaining the exceptions in the first place, or (selectively) unwrap and then rethrow the nested exceptions further up the stack.
About handling legacy code I would recommend you have a look at the book covering the topic:
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
You dont even have to go through the whole book, just look at the things that concern you at the moment.
Also a good book regarding good practices is:
http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?s=books&ie=UTF8&qid=1356340809&sr=1-1&keywords=clean+code
The best approach when handling nested exceptions is refactoring the code and using runtime instead of checked exceptions, and handling those where needed. This way the code is more readable and easier to maintain.
Its depend on the Business logic. You may take action on the exception there itself or you may propogate it all the way upto caller and leave it to the caller for what action he want.
e.g. There are lot of third party API where they don't handle the exception but they throw it from method and hence facilitate API users to take actions as per their need.
e.q. oracle JDBC driver. Driver.getConnection() throws exception. Now caller/API user can handle it as per their need. One may just print stack trace, one may notify admin asking for his attention or one may choose just silently exit the application.
There are two approaches:
To generate a separate exception for each event.
To create a generic exception and describe what caused it
The first approach allows you to write different code for handling the different events, but it requires you to write lot of Exception classes and in some case it could be just too much.
The second approach is more concise, but it makes it difficult to handle the different situations.
As it happens very often in programming the best solution is in the middle, where you balance generating separate exceptions and using one exception for other cases.
The rule of the thumb in this case could be to generate a separate Exception class for the exceptions you want to handle specifically with separate code.
Similarly to the what to throw, we should also have control on what to catch. We can use two approaches for our catch blocks:
A single catch block for all. For example:
catch (Throwable e) {
throw new CommandExecutorException(e);
}
many catch blocks one for each Exception. For example:
} catch (ClassCastException e1) {
...
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}
The first approach is very compact but basically groups every exception in the same case, it's useful only in the situation where all the exceptions are managed equally and do the same thing.
This approach is generally discouraged as it gives no control on the exceptions being catched, leading sometimes to tough bugs, which are also hard to find.
The second approach requires more lines of code but you can execute different operations depending on the exception occurred. This approach is more flexible but in some cases leads your methods to be very long due to exception handling.
I keep getting the dreaded java.something.someException errors while running my java app. and I don't seem to be getting the hang of what exceptions to handle and what not to?
When I read the api docs most of the functions throw exceptions like if I use I/O or use an Array... etc.
How to make a decision about what exceptions to catch and what not to and based on what parameters?
I am talking about checked exceptions here.
Short answer
Catch exceptions that you can deal with then and there, re-throw what you can't.
Long answer
It's called exception-handling code for a reason: whenever you are tempted to write a catch block, you need to have a good reason to catch the exception in the first place. A catch block is stating your intent to catch the exception, and then do something about it. Examples of doing something about it include, but are not limited to:
Retrying the operation that threw the exception. This can make sense in the case of IOException's and other issues that may be temporary (i.e. a network error in the middle of trying to upload a file to a server. Maybe your code should retry the upload a few times).
Logging the exception. Yes, logging counts as doing something. You might also want to re-throw the original exception after logging it so that other code still has a chance to deal with the exception, but that depends on the situation.
Wrapping the exception in another exception that is more appropriate for your class's interface. For example, if you have a FileUploader class, you could wrap IOException's in a more generic UploadFailedException so that classes using your class don't have to have detailed knowledge of how your upload code works (the fact that it throws an IOException is technically an implementation detail).
If the code can't reasonably do anything about the problem at the point where it occurs, then you shouldn't catch it at all.
Unfortunately, such hard-and-fast rules never work 100% of the time. Sometimes, a third-party library you are using will throw checked exceptions that you really don't care about or which will never actually happen. In these cases, you can get away with using an empty catch block that doesn't run any code, but this is not a recommended way to deal with exceptions. At the very least, you should add a comment explaining why you are ignoring the exception (but as CPerkins notes in the comments, "never say never". You may want to actually log these kinds of "never-going-to-happen" exceptions, so just in case such an exception does happen, you are aware of it and can investigate further).
Still, the general rule is, if the method you are in can't do something reasonable with an exception (log it, rethrow it, retry the operation, etc.) then you shouldn't write a catch block at all. Let the calling method deal with the exception. If you are dealing with checked exceptions, add the checked exception to the throws clause of your method, which tells the compiler to pass the exception upwards to the calling method, which may be better suited to handle the error (the calling method may have more context, so it might have a better idea of how to handle the exception).
Usually, it is good to put a try...catch in your main method, which will catch any exceptions that your code couldn't deal with, and report this information to the user and exit the application gracefully.
And finally, don't forget about finally
Also keep in mind that even if you don't write a catch block, you might still need to write a finally block, if you need clean-up code to run regardless of whether the operation you are trying to perform throws an exception or not. A common example is opening up a file in the try block: you'll still want to close the file, even if an exception occurs, and even if your method isn't going to catch the exception. In fact, another common rule of thumb that you might see in tutorials and books is that try...finally blocks should be more common that try...catch blocks in your code, precisely because catch blocks should only be written when you can actually handle the exception, but finally blocks are needed whenever your code needs to clean up after itself.
I highly recommend chapter 9 (Exceptions) in Joshua Bloch's Effective Java, 2nd Edition for these questions.
A general rule of thumb is to handle those exceptions that you can do something about and don't handle those that you can't. In the cases where you don't handle an exception the caller is expected to handle them. If you're writing a framework or a library usually you'll end up wrapping low level exceptions like SQLException in a library or framework specific exception to abstract away the lower level details.
For example, if you're writing a method that writes to a file on disk then you should probably handle FileNotFoundExceptions since you can create the missing file, but if you run into problems creating the file or writing to it then you should probably let the caller handle it (after performing whatever cleanup work needs to be done).
These are my personal findings:
You need a try {} catch (Throwable o) {...} in your main routine so any unexpected exception can be caught, logged and the user told.
Checked exceptions are checked because you need as a programmer to make a decision what to do when they happen. Remember, one decision might be just to say "ok, time to crash".
If you end up with a fatal situation with a checked exception where all you can do is crash, then "throw new RuntimeException("reason", checkedException);" so the handler above have something to log. Include value of important local variables - remember some day you will have to debug a situation where the only thing you have is the stack trace.
Never, ever catch an exception and just ignore it. If you have to then you must document why you are allowed to break the rule, and do it right there, in the catch block.
And a hint that will help you some day: When you crash, provide a simple means to let the user seeing the message email the stack trace to you.
EDIT: Do not be afraid to create new exceptions if the ones available does not completely cover what you need. This allows you to get better naming in stack traces and your error handling code can differentiate between different cases easily. You may want to base all your own exceptions on a common base class ("OurDomainException") so you can use the base class in catch clauses to see if what type it is.
Having coded in Java for a few years, I agree that it is easy to get annoyed by writing endless try-catch blocks.
A good way of coding fast is to catch specific exceptions in as low level as you can, and catch the base Exception at the outermost level (in main()) just so that you can write a generic error message instead of letting the program crash.
This lets you have a running code pretty fast, and then you can take your time to add specific exceptions in various layers with their handling logic.
Catch checked Exception, do not catch RuntimeException. Try to catch specific Exception, try not to catch by generic java.lang.Exception.
Module boundaries
I catch exceptions for cleaner module boundaries, too. For example if there is a SQLException thrown that I can't handle I'll catch it nevertheless and throw my own descriptive exception instead (putting the SQLException as cause). This way the caller doesn't have to know that I'm using a database to fulfill his request. He just gets an error "Cannot handle this specific use case". If I decide to fulfill his request without database access, I don't have to change my API.
As a rule of thumb I catch exceptions where I will be able to do something with then, or where I want the exception to stop moving up. For example, if I am processing a list of items, and I want the next item to be processed even if the others fail, then I will put a try...catch block around that item processing and only in there. I usually put a try...catch(Throwable) in the main method of my program so I can log errors like a class not found or similar stuff.
I don't put a try...catch block in a method if I will not know what to do with that exception. If you do, you will just bloat your code with lots of exception handling code.