tags:

views:

280

answers:

9

Java's checked exceptions sometimes force you to catch a checked exception that you believe will never be thrown. Best practice dictates that you wrap that in an unchecked exception and rethrow it, just in case. What exception class do you wrap with in that case?

What exception would you wrap with in the "// Should never happen" case?

+1  A: 

Any class that is a RuntimeException or a descendant of that doesn't need to be put in the method's throws clause. So if you don't want someone to have to deal with it because it shouldn't happen then use that.

It makes sense for things like "Can't connect to the database" because if your database isn't available your application won't run. So you throw a Runtime exception and the person starting the application sees it as a problem. But you don't need to declare it in your throws all the way up the call stack.

geofflane
+1  A: 

For example, my caveat is the to-UTF-8-bytes character conversion

String.getBytes("UTF-8");

And the need to always wrap it in try-catch as it is a generic method. As UTF-8 could be regarded as standard, I would expect to have a direct String.getUTF8() like call on string, similarly the GetStringUTF8Bytes JNI method.

Of course it could be replaced by a static Charset.UTF8 constant for example and use the getBytes() with that.

Second annoyance for me is the need to wrap the close() into a try-catch. Maybe I'm not that experienced but can't see how it helps when you have already a problem with the stream and you can't even silently close it down for good. You'd practically just log and ignore the exception.

Apparently, you can use a suppressor method call to do just that.

There are also the trivial value-string conversions when you are 100% sure the string is a valid value as you checked it with regex or schema validation.

kd304
Close can throw IOException in certain cases when it actually has to write content (IIRC BufferedOutputStream writes the remaining characters on close() if they weren't otherwise flush()ed). Thus close() sometimes means flush_then_close()
KitsuneYMG
True. Thanks. Never occurred to me as I do flush() manually before close.
kd304
+1  A: 

ImpossibleHappenedException

dfa
+1  A: 

Conditions which should never happen unless the code is not correct should be checked with assertions. That way you can disable them in production builds.

But I don't like to leave a simple assert false; and neither do I want to write silly messages like default case in switch should never fire, x should be nonnull, *this should never happen". It shouldn't, but it did. Whatever. Besides, doesn't it sound a little bit whining when you see a message complaining that something shouldn't have ? Also I wouldn't like to have tons of those messages in the executable, as they are generally never used, and each of them is relevant only to some one small function, out of thousands of functions.

So I do like

 assert false : "Programming Error"

Programming error is exactly what prevented the application from working so it fits perfectly the situation.

 switch (x)
 {
     case GO_FORWARD:
          ... break
     case BUY_SWORD;
          ... break
     default:
          assert false : "Programming Error"
 }


 /* at this point, we have already had checked that
    we have the money */
 try {
      buy_sword(); buy_elixir();
 } catch (InsufficientFunds) {
      /* if the code was correct, the funds would be sufficient
         so this event means the code is broken. Telling
         the user something like "Funds should be sufficient"
         won't be helpful to the user, so we put in a generic error message */
      throw new AssertionError("Programming Error");
 }

If you want to run these checks at all times, then instead of

 assert false : "Programming Error"
 assert expr : "Programming Error"

do

 if (! expr)
      throw new Exception("Programming Error")

or even derive ProgrammingError exception class.

Adrian Panasiuk
Assertion don't run under normal circumstances. That means that is during testing (with -ea) if you don't hit one of your assert statements, you could silently continue on in an undefined state (unless your production code also uses -ea).
KitsuneYMG
I agree this is a problem. Tests run without assertions may miss problems. When running tests only with assertions you risk that the assertions are broken and have side effects. So if you have assertions disabled in production, you have to run the tests twice. I advocate for using assertions, but having them enabled in all - including production - builds.
Adrian Panasiuk
+2  A: 

I use AssertionError with the string This should never happen.

KitsuneYMG
I use RuntimeException with "This should not happen."
sal
I use AssertionError because its not caught by catch(Exception). Yes some people do code that way.
KitsuneYMG
Replting to self. I have been guilty of catching Exception before, mainly when using reflection. In general its something like load a class from a property and newInstance it. If it fails, go on with you life [log it]. For stuff like view plugins (before OSGi) I did this a lot.
KitsuneYMG
+1  A: 

I like "Unreachable code reached"

David Hedlund
+2  A: 

I don't yet have one, but I'd do it the following way:

  • have it extend Error rather then Exception/RuntimeException, since then it's less likely to be caught by an error handler which is not prepared for it;
  • wrap it in some static utility calls:

Example:

public static void doAssert(boolean result, String reason) {

    if ( !result ) 
        throw new OMGWereDoomedError("Assertion failed: " + reason + " .");
}

I prefer these wrapper since I can then change the implementation if needed.

Also, I don't advocate using assertions since I don't always control the runtime flags, but I do want execution to halt abruptly if the system is compromised.

Consider this:

  • showing the user a Sorry, we're unable to process your payment page;
  • confirming the result to the user, even though the system is in an uncertain state.

Which would you choose?

Robert Munteanu
+1 for the error class name :D
Yuval
Error is reserved. A reasonable application should not try to catch: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Error.html
dfa
@dfa: I agree, and it's a pretty thin line I'm walking. However, I'd rather get these in the uncatchExceptionHandler rather than in some generic catch ( Exception e ) block.
Robert Munteanu
A: 

This applies more to the original version of the question, before the question was edited to deal specifically with catching checked exceptions.

Disclaimer: I originally posted a snippet of this in a comment on the question because the question was closed at that point in time.

int salary = ...;

if (salary == 0) {
    // ...
} else if (salary < 0) {
    // ...
} else if (salary > 0) {
    // ...
} else {
    throw new IllegalStateException("The fundamental mathematics of the universe have been compromised");
}
Adam Paynter
+1  A: 

Should never happen is an Error more than an Exception. An exception describes a situation, that you possibly can handle. How do you want to handle the unexpected? And as it is an assertion, that this particular exception should never happen, I would use an AssertionError.

Mnementh