\"The major difference between a thing that might go wrong and a thing that cannot possibly go wrong is that when a thing that cannot possibly go wrong go
Consider using the form
throw new RuntimeException("This should never happen", e);
instead. This allows you to convey meaning to the maintainer to follow you, both when reading the code but also SHOULD the exception happen to be thrown in some strange scenario.
EDIT: This is also a good way to pass exceptions through a mechanism not expecting those exceptions. E.g. if you have a "get more rows from the database" iterator the Iterator interface does not allow to throw e.g. an FileNotFoundException so you can wrap it like this. In the code USING the iterator, you can then catch the runtimeexception and inspect the original excpetion with getCause(). VERY useful when going through legacy code paths.
If your position is that this is so unlikely and should just end the program, use an existing runtime exception, even RuntimeException itself (if not IllegalStateException).
try {
....
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Don't just tank your entire application with a RuntimeException
when you encounter an unlikely error condition. RuntimeException
should be reserved for programmer errors, and IOException
is most likely not caused by programmer error.
Instead, encapsulate the lower level exception in a higher level exception and rethrow. Then handle the higher level exception up the call chain.
For example:
class SomeClass {
public void doActions() {
try {
someAction();
} catch (HigherLevelException e) {
notifyUser();
}
someOtherUnrelatedAction();
}
public void someAction() throws HigherLevelException {
try {
// user lower-level abstraction to do our bidding
} catch(LowerLevelException e) {
throw new HigherLevelException(e);
}
}
public void someOtherUnrelatedAction() {
// does stuff
}
}
Most likely the call stack that threw the exception was performing some task in your application. Instead of force crashing your entire application with a RuntimeException
figure out what to do when the problem occurs during that task. For example, were you trying to save a file? Don't crash, instead notify the user there was an issue.
You are probably better off throwing the superclass and more generic exception IOException
at any point in your code which involves reading or writing from the file.
The file may exist when your class's constructor runs, but that doesn't guarantee that:
etc.
Instead of reinventing the wheel, I would say just re-throw IOException wherever the JDK/java.io
classes you are using force you to do so.
Also I for one hate classes that throw Exceptions from their constructor - I'd get rid of these if I were you.
The usual pattern to deal with this is exception chaining. You just wrap the FileNotFoundException in a RuntimeException:
catch(FileNotFoundException e) {
throw new RuntimeException(e);
}
This pattern is not only applicable when an Exception cannot occur in the specific situation (such as yours), but also when you have no means or intention to really handle the exception (such as a database link failure).
Edit: Beware of this similar-looking anti-pattern, which I have seen in the wild far too often:
catch(FileNotFoundException e) {
throw new RuntimeException(e.getMessage());
}
By doing this, you throw away all the important information in the original stacktrace, which will often make problems difficult to track down.
Another edit: As Thorbjørn Ravn Andersen correctly points out in his response, it doesn't hurt to state why you're chaining the exception, either in a comment or, even better, as the exception message:
catch(FileNotFoundException e) {
throw new RuntimeException(
"This should never happen, I know this file exists", e);
}
I did a little googling and found this glob of code. It's a bit more flexible of an approach me thinks
Compliments of this article
class SomeOtherException extends Exception {}
public class TurnOffChecking {
private static Test monitor = new Test();
public static void main(String[] args) {
WrapCheckedException wce = new WrapCheckedException();
// You can call f() without a try block, and let
// RuntimeExceptions go out of the method:
wce.throwRuntimeException(3);
// Or you can choose to catch exceptions:
for(int i = 0; i < 4; i++)
try {
if(i < 3)
wce.throwRuntimeException(i);
else
throw new SomeOtherException();
} catch(SomeOtherException e) {
System.out.println("SomeOtherException: " + e);
} catch(RuntimeException re) {
try {
throw re.getCause();
} catch(FileNotFoundException e) {
System.out.println(
"FileNotFoundException: " + e);
} catch(IOException e) {
System.out.println("IOException: " + e);
} catch(Throwable e) {
System.out.println("Throwable: " + e);
}
}
monitor.expect(new String[] {
"FileNotFoundException: " +
"java.io.FileNotFoundException",
"IOException: java.io.IOException",
"Throwable: java.lang.RuntimeException: Where am I?",
"SomeOtherException: SomeOtherException"
});
}
} ///:~