views:

57

answers:

2

Say I have the following line in a method:

 String encodedString = URLEncoder.encode(foo, "utf-8");

this method throws an UnsupportedEncodingException. Which is better:

/** @throws UnsupportedEncodingException umm...never
 */
public void myMethod() throws UnsupportedEncodingException {
   ...
   String encodedString = URLEncoder.encode(foo, "utf-8");
   ...
}

(forcing the caller to catch this himself) Or:

public void myMethod() {
   try {
     ...
     String encodedString = URLEncoder.encode(foo, "utf-8");
     ...
   catch(UnsupportedEncodingException e) {
      Logger.log("cosmic ray detected!");
   }

}

Or is there a more elegant way of handling exceptions which can't really ever occur?

+3  A: 

If you can pretty much guarantee that the exception can never occur, then it's better to localize this assertion at the narrowest scope rather than letting it propagate, because other people may not realize that this is the case without looking at documentations.

If a method is declared to throw something, then there should be scenarios where it actually does. If it's pretty much guaranteed to never does, then it's better to omit the throws clause altogether and simplify your API.

You should always throw exceptions appropriate to your level of abstraction (Effective Java 2nd Edition, item 61). Declaring that you might throw something, when it's guaranteed never to occur, breaks this design guideline.

polygenelubricants
+7  A: 

Never say never ;)

In the example above you could always catch the exception then throw a RuntimeException:

public void myMethod() {
   try {
      ...
      String encodedString = URLEncoder.encode(foo, "utf-8");
       ...
   } catch(UnsupportedEncodingException e) {
     throw new RuntimeException("This should not be possible",e);
   }

}

That way the caller isn't forced to catch something you 99.999% sure will never happen, but in the crazy event that it does happen you still get an exception bubble up to a point where you'll hopefully notice it and be able to quickly realize what's changed and fix it.

HTH

simonlord
both answers are great but I'm accepting this because of the RuntimeException idea, which is great. Maybe an IllegalStateException would make sense here...
Epaga
Another possibility is `throw new AssertionError("this cannot happen", ex)`
Stephen C