Handling RuntimeExceptions in certain circumstances valid?

97 views Asked by At

As I understand it from several tutorials, RuntimeExceptions are actually not supposed to be caught, because they shall reveal inappropiate usage of methods, especially APIs, correct?
Furthermore, one might assume that the program is not able to recover from RuntimeExceptions.
Now, I experienced a case where I might receive an IndexOutOfBoundsException due to invalid user input: the program receives a String from a HTML-form and wants to validate it if it contains an integer.
Basically the assigned String is matched with a pattern and then the comma's position is determined. Afterwards, it's necessary to examine the first digit behind the comma to decide how to round it correctly. That's the critical part:

        firstDecimalChar = formattedValue.charAt(dotPosition + 1);

This statement throws the Exception if the user entered something like "27." Due to the fact that this is based on weird user input, I wondered if this Exception actually behaves like a common exception (so to say).
The reason I think this is that in most tutorials (e.g. oracle) they categorize checked Exceptions as errors which result from invalid input, i.e. wrong path name to a file that shall be opened, and with some correction or a user hint it's possible to recover from that error. Same here: one might simply set above variable to zero, because that's what it means when somebody inserts "27." -> "27.0"

Is that catch and specify requirement really that strict? Of course, one can simple check beforehand if the position isn't out of bounds, but my question is if there is really such a straight line between checked and unchecked exceptions. I'm wondering if there are any technical disadvantages why exceptions should be avoided as often as possible. (Somebody mentioned JVM-overhead, but is it that significant?)

I think I need some more in-depth clarification here, because most tutorials don't convince me with: "you simply shouldn't do that". Because I think in this case, this exception behaves like a checked Exception from which it is easy to recover from.

Note: In my code I check if the string position is valid or not beforehand and don't catch the exception - so that's not part of this question : ) But this case keeps me busy, still.

4

There are 4 answers

5
aioobe On BEST ANSWER

Is that catch and specify requirement really that strict?

No, I think its ok to catch unchecked exceptions (RuntimeExceptions) in certain situations.

For example, if a user enters a number, I think it's perfectly fine to do

double i;
try {
    i = Double.parseDouble(userInput);
} catch (NumberFormatException e) {
    addValidationError("Entered number is not valid: " + userInput);
}

If an exception is unexpected and corresponds to an error in the code, don't bother catching it (or catch in at the top most level, such as in handleRequest or whatever, and return a 500 error for example). On the other hand, if you can foresee an exception being thrown, (and it's problematic to use ordinary control structures such as if statements to cover those cases, such as in the NumberFormatException example above) catch it and handle it.

As it happens, RuntimeExceptions often correspond to programmer errors, and saying "don't catch RuntimeExceptions" can probably be seen as a good approximation of what to catch and not to catch.

When a developer decides whether to extend Exception or RuntimeException he/she will think about whether it's reasonable to force the clients to declare throws clauses / catch the exception. In some cases an exception can be a due to both a programming error and a "normal operation" error. In such cases it's kind of impolite to force throws/catch upon the clients, and it's more suitable to make it a RuntimeException. In client code, where the exception is in fact used to indicate "normal operation" error, it is still appropriate to catch it.

Related question (but closed as primarily opinion-based): stackoverflow.com/questions/24344511/why-is-catching-a-runtimeexception-not-considered-a-good-programming-practice

1
Audrius Meškauskas On

Some runtime or third party methods (like Integer.parseInt) report the validation error through exception. If we need this validation functionality, we need to catch the exception.

It would probably be better to have something like Integer.isValid(String x) but abundant homegrown replacements of standard libraries are also problematic.

1
Chetan Kinger On

As I understand it from several tutorials, RuntimeExceptions are actually not supposed to be caught, because they shall reveal inappropiate usage of methods, especially APIs, correct?

Not really. You can always catch a RuntimeException and wrap it in a checked Exception and throw it back to the caller for them to decide whether to kill the app or wrap up the error in a format that can be understood by the user

Example :

try {
    //read parameters
    String processType = args[9]; 
    String username = args[11];
    //read more parameters..
} catch (ArrayIndexOutOfBoundsException e) {
   throw new InvalidInputException("Wrong number of input parameters passed. See usage notes"+e);
}
2
Roy T. On

I think a Runtime exception signifies something that should really never happen during the execution of a program. For example an IOException is not a runtime exception: an IOException happens because something outside the control of the program (the filesystem in this case) is misbehaving.

However, an ArrayIndexOutOfBoundsException happens while the program is in complete control. So it is a RuntimeException. It signifies that the programmer did something wrong. For example a wrong calculation of an array index.

Let's image a program that does not interact with the outside world at all (no IO, etc..) this program should never throw an Exception because it is in complete control of everything that happens. If it does throw an Exception it means the programmer did something wrong (or was very lazy).

Note: I completely rewrote this answer because I first didn't see the note at the end of the question :)