How do you handle "impossible" exceptions in Java? - java

Sometimes, I'll end up having to catch an exception that I know can never happen, such as here
URLDecoder.decode("some string", "UTF-8"); //No unknown encoding possible
or here:
public void methodWithURL(URL url){
URI uri = new URI(url); //No invalud URI syntax possible
}
How do you handle this? I generally log a funny error regarding how the laws of the universe have changed, and then throw a RuntimeException. Is there a better way?

I catch the Exception and wrap it in an Error. from the doc of Error :
An Error is a subclass of Throwable that indicates serious problems
that a reasonable application should not try to catch.

I would skip the funny message.
BTW: I had a case where a piece of code (in a small library) just assumed that an encoding would be available. Only it got deployed on a limited device and exploded at runtime.
Checked exceptions serve to show places in our code where we should pause for a second and consider the paths less traveled (as in "what my app does when network dies" and other corner cases). Wrapping them in IllegalStateException and rethrowing is a sort of a signed contract, where the programmer says: "yes, all risks considered I take full responsibility for the spot right here". If it wasn't for checked exceptions, we would hava no way of knowing a consious decision from a plain lack of thought.

Well, IMHO there is a better way than "log[ging] a funny error regarding how the laws of the universe have changed" because in doing so you are "being cute," which among friends is fine but is not universally (no pun intended) accepted. Your code may be read by others and if your humor falls flat (on them) you haven't really made any friends.
Many style guides make suggestions for impossible exceptions. You can use an empty catch block with the exception parameter being named willNeverHappen; you can place a comment in the empty block; you can throw a runtime exception (probably the best, since you MIGHT misspell UTF-8!)
If you want to be super ambitious, you can write an annotation, like SneakyThrows in Lombok. Whether you would consider this "better" is simply a matter of taste. :)
Note that this question was discussed on https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-cannot-ever-be-thrown.

Here's my solution -- developed for Android but can be easily adapted for "regular" Java:
public class ImpossibleException extends RuntimeException {
public ImpossibleException(#NonNull String whyNotPossible) {
this(whyNotPossible, null);
}
public ImpossibleException(#NonNull String whyNotPossible, Throwable throwable) {
super("Impossible exception: " + whyNotPossible, throwable);
Log.e("Impossible", whyNotPossible, throwable);
}
}
Usage:
try {
byte[] data = "Hello".getBytes("utf-8");
Log.i("Test", "data.length=" + data.length);
} catch (UnsupportedEncodingException e) {
throw new ImpossibleException("Android always supports utf-8", e);
}
The whyNotPossible constructor means there's no need to log the error where it happens, and there's also no need for a comment.
I guess it's a matter of taste if this should be an ImpossibleException extends RuntimeException or an ImpossibleError extends Error.

If you use Lombok in your project, you can annotate the surrounding method with #SneakyThrows which kind of hides checked exceptions in RuntimeException (thus no need to surround by try-catch nor declare it in throws clause).
For instance:
#SneakyThrows(URISyntaxException.class)
public void methodWithURL(URL url){ // No throws here
URI uri = new URI(url); // Assume no invalud URI syntax possible
}

Related

Are exceptions well handeled in this code? Is it missing a finally block to close the fileobject?

void appendFile() throws IOException{
FileWriter print = new FileWriter(f, true);
String info = GetData.getWord("Write desired info to File");
print.append(" "); //Write Data
print.append(info);
System.out.println("this executes");
print.flush();
print.close();
}
boolean fileExist(){
return f.exists();
}
try{
if (f.fileExist())
f.appendFile();
else {
throw new IOException();
}
}
catch(IOException e) {
e.printStackTrace();
}
I'm not sure if the ecxeption is well handeled? The FileWriter is not going to be created if there is a fileNotFoundException, therefore don't need to be closed. However, is it possible that this code throws another kind of IOException after the file was opened?, and in that case do I need a finally block to close the file.
No.
It doesn't safely close the resource
The general rule is, if you call a constructor of an object that represents a closable resource, or a method that returns one which documents that this counts as 'opening the resource', which often but not always includes new being part of the method name (examples: socket.getInputStream(), Files.newInputStream), then you are responsible for closing it.
The problem is, what if an exception occurs? So, you have to use try/finally, except that's a mouthful, so there's a convenient syntax for this.
The appendFile method should use it; it isn't, that makes it bad code. This is correct:
try (FileWriter print = new FileWriter(f, true)) {
String info = GetData.getWord("Write desired info to File");
print.append(" "); //Write Data
print.append(info);
System.out.println("this executes");
}
Not how it is not neccessary to flush before close (close implies flush), and in this case, not neccessary to close() - the try construct does it for you. It also does it for you if you get out of the {} of the try via a return statement, via control flow (break), or via an exception, or just by running to the } and exiting normally. No matter how - the resource is closed. As it should be.
It throws description-less exceptions
else throw new IOException(); is no good; add a description that explains why the exception happened. throw new IOException("File not found") is better, but throw new FileNotFoundException(f.toString()) is even better: The message should convey useful information and nothing more than that (in other words, throw new IOException("Something went wrong") is horrible, don't do that, that message adds no useful information), should not end in punctuation (throw new IOException("File not found!") is bad), and should throw a type that is most appropriate (if the file isn't there, FileNotFoundException, which is a subtype of IOException, is more appropriate, obviously).
It commits the capital offense
You should not ever write a catch block whose contents are just e.printStackTrace();. This is always wrong.
Here's what you do with a checked exception:
First, think of what the exception means and whether the nature of your method inherently implies that this exception can occur (vs. that it is an implementation detail). In this case, you didn't show us what the method containing that try/catch stuff even does. But let's say it is called appendFile, obviously a method that includes the text 'file' does I/O, and therefore, that method should be declared with throws IOException. It's not an implementation detail that a method named appendFile interacts with files. It is its nature.
This is somewhat in the eye of the beholder. Imagine a method named saveGame. That's less clear; perhaps the mechanism to save may involve a database instead, in which case SQLException would be normal. That's an example of a method where 'it interacts with the file system' is an implementation detail.
The problem that the exception signals is logical, but needs to be more abstract.
See the above: A save file system can obviously fail to save, but the exact nature of the error is abstract: If the save file system is DB-based, errors would show up in the form of an SQLException; if a file system, IOException, etcetera. However, the idea that saving may fail, and that the code that tried to save has a reasonable chance that it can somewhat recover from this, is obvious. If it's a game, there's a user interface; you should most absolutely TELL the player that saving failed, instead of shunting some stack trace into sysout which they probably never even look at! Telling the user that something failed is one way of handling things, not always the best, but here it applies).
In such cases, make your own exception type and throw that, using the wrapper constructor:
public class SaveException extends Exception {
public SaveException(Throwable cause) {
super(cause);
}
}
// and to use:
public void save() throws SaveException {
try {
try (OutputStream out = Files.newOutputStream(savePath)) {
game.saveTo(out);
}
} catch (IOException e) {
throw new SaveException(e);
}
}
If neither applies, then perhaps the exception is either essentially not handleable or not expectable or nearly always a bug. For example, writing to an outputstream that you know is a ByteArrayOutputStream (which can't throw), trying to load the UTF-8 charset (which is guaranteed by the JVM spec and therefore cannot possibly throw NoSuchCharsetException) - those are not expectable. Something like Pattern.compile("Some-regexp-here") can fail (not all strings are valid regexps), but as the vast majority of regexes in java are literals written by a programmer, any error in them is therefore neccessarily a bug. Those, too, are properly done as RuntimeExceptions (which are exceptions you don't have to catch or list in your throws line). Not handleables are mostly an application logic level thing. All fair game for runtimeexceptions. Make your own or use something that applies:
public void save(int saveSlot) {
if (saveSlot < 1 || saveSlot > 9) throw new IllegalArgumentException("Choose a saveslot from 1 to 9");
// ... rest of code.
}
This really feels like door number one: Whatever method this is in probably needs to be declared as throws IOException and do no catching or trying at all.
Minor nit: Uses old API
There's new API for file stuff in the java.nio.file package. It's 'better', in that the old API does a bunch of bad things, such as returning failure by way of a boolean flag instead of doing it right (by throwing an exception), and the new API has far more support for various bits and bobs of what file systems do, such as support for file links and creation timestamps.

Exception handling in separate method for readability

Is it an anti-pattern to handle exception in a separate method?
Say i have a method that does some low-level IO and may throw an IOException, and i have a method foo() that calls the low-level IO method several times. Does it make sense to do the exception-handling in a 3rd method like this:
public void foo() throws MyCheckedException {
// some stuff
goDoSomeIO(path1)
// some other stuff
goDoSomeIO(path2)
// some more stuff
goDoSomeIO(path3)
}
private String goDoSomeIO(String filePath) throws MyCheckedException {
try {
doSomeIO(filePath);
} catch (IOException ioe) {
LOG.error("Io failed at: " + filePath);
throw new MyCheckedException("Process failed because io failed", ioe)
}
}
private String doSomeIO(String filepath) throws IOException {
//io stuff
}
I find this is more readable than it would be if the doSomeIO method did its own exception handling, or if the exception handling happend in foo.
I frequently see code that handles exceptions of lower level methods at a higher level, regardless if the lower level is just one method or several.
That's quite common and is due to segregated concerns: Low level stuff takes care of pushing files around, high level stuff catches exceptions to determine if a complex operation worked or not. I don't think there's anything wrong with putting the handling of IO and handling of IO in different methods. (I'd try to give them some name, that explains the purpose however. I'm not a fan of goDoWhatever & doWhatever)
The general rule of catching [checked] exception is to do it when you can recover from the 'exceptional' situation that occurred. If you can't recover from the exception here, let it bubble up to a level at which it can be recovered. For example, notify the user the selected file is unreadable and allow the user to select a file again. Or to send a 404 'page' to the requester when the actually requested page doesn't exist.
Effective Java, Item 58
A commonly used exception to this rule is to catch, do some trivial non-recovering work (like logging) and rethrow the exception (possibly wrapped). I see nothing wrong with your approach.
It's actually a pro-pattern to add extra details to the exception and rethrowing it.

Exceptions in Java

At the moment I am developing a website while using the Playframework2. I am just a beginner in programming. I read some books about exceptions but now in the real world , exception handling is really strange.
To be honest I don't really care what exceptions are thrown I handle all exceptions the same way.
return badrequest(); . I only use exceptions for logging.
try{
...
}
catch(Exeption e){
//log
return badrequest();
}
But this is so much boilerplate and it's really annoying to write, because every method throws the same exceptions.
Any tips , hints or resources that you could give me?
edit:
An example would be my "global" config file. Because I need to connect to the db every time I thought i could write a singleton for this problem.
private Datastore connect() throws UnknownHostException, MongoException,
DbAuthException {
Mongo m = new Mongo(dbUrl, dbPort);
Datastore ds = new Morphia().createDatastore(m, dbName);
boolean con = ds.getDB().authenticate(username, password.toCharArray());
if (!con)
throw new DbAuthException();
return ds;
}
This also results in a try and catch every time I want to connect to the db. My problem is I don't think I can handle them diffidently.
A code example :
public static Result addComment(String title) {
try {
Datastore ds = DatabaseConnect.getInstance().getDatastore();
Form<Comment> filledForm = commentForm.bindFromRequest();
Comment userComment = filledForm.get();
userComment.setUsername(Util.getUsernameFromSession(ctx()));
User.increasePointsBy(ctx(), 1);
UserGuides.addComment(title, userComment);
} catch (Exception e) {
return badRequest();
}
return redirect(routes.Guides.blank());
}
In this case I was to lazy to write the same try and catch over and over again, and this is duplicated code.
Maybe there is a book that explains how to design a big application with exception handling?
When you invoke a method, you do not necessarily have to catch the exceptions right there. You can let your callers handle them (declaring a throws clause if it is a checked exception). In fact, the ability to pass them on to the callers without any additional work is the distinguishing feature of exceptions.
My team has adopted the following coding standard: We throw checked exceptions for those rare cases when we want to recover from a failure, and unchecked exceptions for anything else. There is only a single catch block for the unchecked exceptions in a method so high in the call stack that all requests pass through it (for instance in a ServletFilter). This catch block logs the exception, and forwards the user to the "Sorry, this shouldn't have happened" page.
Have you looked at your code to examine why you're throwing all these exceptions? Exceptions are there for a reason- to tell you that something went wrong. If you're writing too much "boilerplate" try-catch code and you're not in a thousand line application, you have to refactor.
try-catch can be irritating when you have a complex block and can become very monotonous and boilerplate (Marc Gravell even said he usually uses try-finally) but as a new programmer, it would be helpful for you to examine the code that you write and figure out how to either handle or avoid those exceptions.
As akf mentions, ignoring exceptions can also be hazardous to debugging. It will be harder to track down where something catastrophic went wrong if you're missing exceptions leading up to it.

Is it a bad practice to catch Throwable?

Is it a bad practice to catch Throwable?
For example something like this:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Is this a bad practice or we should be as specific as possible?
You need to be as specific as possible. Otherwise unforeseen bugs might creep away this way.
Besides, Throwable covers Error as well and that's usually no point of return. You don't want to catch/handle that, you want your program to die immediately so that you can fix it properly.
This is a bad idea. In fact, even catching Exception is usually a bad idea. Let's consider an example:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
inputNumber = 10; //Default, user did not enter valid number
}
Now, let's say that getUserInput() blocks for a while, and another thread stops your thread in the worst possible way ( it calls thread.stop() ). Your catch block will catch a ThreadDeath Error. This is super bad. The behavior of your code after catching that Exception is largely undefined.
A similar problem occurs with catching Exception. Maybe getUserInput() failed because of an InterruptException, or a permission denied exception while trying to log the results, or all sorts of other failures. You have no idea what went wrong, as because of that, you also have no idea how to fix the problem.
You have three better options:
1 -- Catch exactly the Exception(s) you know how to handle:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
inputNumber = 10; //Default, user did not enter valid number
}
2 -- Rethrow any exception you run into and don't know how to handle:
try {
doSomethingMysterious();
} catch(Exception e) {
log.error("Oh man, something bad and mysterious happened",e);
throw e;
}
3 -- Use a finally block so you don't have to remember to rethrow:
Resources r = null;
try {
r = allocateSomeResources();
doSomething(r);
} finally {
if(r!=null) cleanUpResources(r);
}
Also be aware that when you catch Throwable, you can also catch InterruptedException which requires a special treatment. See Dealing with InterruptedException for more details.
If you only want to catch unchecked exceptions, you might also consider this pattern
try {
...
} catch (RuntimeException exception) {
//do something
} catch (Error error) {
//do something
}
This way, when you modify your code and add a method call that can throw a checked exception, the compiler will remind you of that and then you can decide what to do for this case.
straight from the javadoc of the Error class (which recommends not to catch these):
* An <code>Error</code> is a subclass of <code>Throwable</code>
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The <code>ThreadDeath</code> error, though a "normal" condition,
* is also a subclass of <code>Error</code> because most applications
* should not try to catch it.
* A method is not required to declare in its <code>throws</code>
* clause any subclasses of <code>Error</code> that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* #author Frank Yellin
* #version %I%, %G%
* #see java.lang.ThreadDeath
* #since JDK1.0
It's not a bad practice if you absolutely cannot have an exception bubble out of a method.
It's a bad practice if you really can't handle the exception. Better to add "throws" to the method signature than just catch and re-throw or, worse, wrap it in a RuntimeException and re-throw.
Catching Throwable is sometimes necessary if you are using libraries that throw Errors over-enthusiastically, otherwise your library may kill your application.
However, it would be best under these circumstances to specify only the specific errors thrown by the library, rather than all Throwables.
The question is a bit vague; are you asking "is it OK to catch Throwable", or "is it OK to catch a Throwable and not do anything"? Many people here answered the latter, but that's a side issue; 99% of the time you should not "consume" or discard the exception, whether you are catching Throwable or IOException or whatever.
If you propagate the exception, the answer (like the answer to so many questions) is "it depends". It depends on what you're doing with the exception—why you're catching it.
A good example of why you would want to catch Throwable is to provide some sort of cleanup if there is any error. For example in JDBC, if an error occurs during a transaction, you would want to roll back the transaction:
try {
…
} catch(final Throwable throwable) {
connection.rollback();
throw throwable;
}
Note that the exception is not discarded, but propagated.
But as a general policy, catching Throwable because you don't have a reason and are too lazy to see which specific exceptions are being thrown is poor form and a bad idea.
Throwable is the base class for all classes than can be thrown (not only exceptions). There is little you can do if you catch an OutOfMemoryError or KernelError (see When to catch java.lang.Error?)
catching Exceptions should be enough.
it depends on your logic or to be more specific to your options / possibilities. If there is any specific exception that you can possibly react on in a meaningful way, you could catch it first and do so.
If there isn't and you're sure you will do the same thing for all exceptions and errors (for example exit with an error-message), than it is not problem to catch the throwable.
Usually the first case holds and you wouldn't catch the throwable. But there still are plenty of cases where catching it works fine.
Although it is described as a very bad practice, you may sometimes find rare cases that it not only useful but also mandatory. Here are two examples.
In a web application where you must show a meaning full error page to user.
This code make sure this happens as it is a big try/catch around all your request handelers ( servlets, struts actions, or any controller ....)
try{
//run the code which handles user request.
}catch(Throwable ex){
LOG.error("Exception was thrown: {}", ex);
//redirect request to a error page.
}
}
As another example, consider you have a service class which serves fund transfer business. This method returns a TransferReceipt if transfer is done or NULL if it couldn't.
String FoundtransferService.doTransfer( fundtransferVO);
Now imaging you get a List of fund transfers from user and you must use above service to do them all.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}
But what will happen if any exception happens? You should not stop, as one transfer may have been success and one may not, you should keep go on through all user List, and show the result to each transfer. So you end up with this code.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}catch(Throwable ex){
LOG.error("The transfer for {} failed due the error {}", foundtransferVO, ex);
}
}
You can browse lots of open source projects to see that the throwable is really cached and handled. For example here is a search of tomcat,struts2 and primefaces:
https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
Generally speaking you want to avoid catching Errors but I can think of (at least) two specific cases where it's appropriate to do so:
You want to shut down the application in response to errors, especially AssertionError which is otherwise harmless.
Are you implementing a thread-pooling mechanism similar to ExecutorService.submit() that requires you to forward exceptions back to the user so they can handle it.
Throwable is the superclass of all the errors and excetions.
If you use Throwable in a catch clause, it will not only catch all exceptions, it will also catch all errors. Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an application. Typical examples for that are the OutOfMemoryError or the StackOverflowError. Both are caused by situations that are outside of the control of the application and can’t be handled. So you shouldn't catch Throwables unless your are pretty confident that it will only be an exception reside inside Throwable.
If we use throwable, then it covers Error as well and that's it.
Example.
public class ExceptionTest {
/**
* #param args
*/
public static void m1() {
int i = 10;
int j = 0;
try {
int k = i / j;
System.out.println(k);
} catch (Throwable th) {
th.printStackTrace();
}
}
public static void main(String[] args) {
m1();
}
}
Output:
java.lang.ArithmeticException: / by zero
at com.infy.test.ExceptionTest.m1(ExceptionTest.java:12)
at com.infy.test.ExceptionTest.main(ExceptionTest.java:25)
A more differentiated answer would be: it depends.
The difference between an Exception and an Error is that an Exception is a state that has to be expected, while an Error is an unexpected state, which is usually fatal. Errors usually cannot be recovered from and require resetting major parts of the program or even the whole JVM.
Catching Exceptions is something you should always do to handle states that are likely to happen, which is why it is enforced by the JVM. I.E. opening a file can cause a FileNotFoundException, calling a web resource can result in a TimeoutException, and so on. Your code needs to be prepared to handle those situations as they can commonly occur. How you handle those is up to you, there is no need to recover from everything, but your application should not boot back to desktop just because a web-server took a little longer to answer.
Catching Errors is something you should do only if it is really necessary. Generally you cannot recover from Errors and should not try to, unless you have a good reason to. Reasons to catch Errors are to close critical resources that would otherwise be left open, or if you i.E. have a server that runs plugins, which can then stop or restart the plugin that caused the error. Other reasons are to log additional information that might help to debug that error later, in which case you of course should rethrow it to make sure the application terminates properly.
Rule of thumb: Unless you have an important reason to catch Errors, don't.
Therefore use catch (Throwable t) only in such really important situation, otherwise stick to catch (Exception e)

how and where to catch exceptions in a j2ee application

ok, im working in a j2ee project that has 2 branches in the repo and i'm ordered to mix them.
i was coding and then netbeans ask me "unreported exception blah bla bla must be caugth or declared to be thrown" and gives me the choice of just handle each exception or just throw it hoping someone else catches.
The classes i'm working with are these:
DataBase - DataObject - PersonDB(I'm working here)
DataBase an abstraction of the DBMS(supports a couple of them)
DataObject is just the CRUD, type conversion between the DBMS and java , and some reflection things for generality, it uses Database as a member variable
PersonDB is a map of the fields in the table called person to java types, this class extends DataObject
Now in the version 1(just the name actually worked in parallel) catch all the exceptions where they are produced for example in the class DataBase:
try {
Class.forName(this.driver);
} catch (ClassNotFoundException ex) {
Logger.getLogger(BD.class.getName()).log(Level.SEVERE, null, ex);
}
or in the DataObject class catching:
SQLException, NoSuchFieldException, IllegalArgumentException
now on version 2 all that is left to the up caller like this:
public BD (String Adriver, String Ahost, String Abase, String Alogin, String Apassword)
throws java.lang.ClassNotFoundException { ... }
which is the best way to go in your oppinion in this kind of issues, specially if i'm using struts
I apologize for my English
Well the first question I have to ask is: if this is a J2EE application, what are you doing manually loading JDBC drivers? This is what data sources are for.
Secondly, if you do need to dot his then ask yourself this: what is the result of this exception happening? Is it recoverable? Or is the failure so catastrophic your application can't run?
If it's so catastrophic your application can't run do this:
try {
...
} catch (SomeCheckedException e) {
throw new RuntimeException(e);
}
There is no point polluting your interfaces with "throws ..." clauses.
Alternatively if it is recoverable or potentially recoverable then you do need to handle it more nicely. It's hard to give an answer as to how though. Really it depends on the circumstances.
For example, if you're loading modules/plugins this way, you just log that plugin XYZ could not be loaded (logging the exception) and move on. If this is the direct result of a user action you need to somehow report to the user that the action failed (and also log the error), etc.
Exception handling is always a question of "Can i handle it?" - where handle means more than log and rethrow.
Sometimes it is worth to catch just to throw an exception of an other abstraction level ("Can i produce a more clear error for the caller?").
In both cases you have to think about passing the cause or not ("Has it useful informaton for the caller?") - not just do it any time, you will get tons of useless log files. When catching an exception, you would normally log the catched exception, maybe with debug level only, but in case of debugging a customers system, good log information is often the only chance to "debug" the system.
Exception handling and logging is often not done well. But for a product or longtime project it would be a good investment.

Categories