79

On a recent project I recommended catching a RuntimeException within a test harness code and logging it. The code processes a series of inputs from a database, and I do not want the test to stop due to failure of any one input (Null values, Illegal arguments, etc.). Needless to say, my suggestion triggered a passionate discussion.

Is catching any kind of RuntimeException acceptable? If yes, what are other scenarios where it is OK to catch RuntimeExceptions?

james.garriss
  • 12,959
  • 7
  • 83
  • 96
VDev
  • 2,287
  • 5
  • 25
  • 27

10 Answers10

112

You catch RuntimeException for the same reason that you catch any exception: You plan to do something with it. Perhaps you can correct whatever caused the exception. Perhaps you simply want to re-throw with a different exception type.

Catching and ignoring any exception, however, is extremely bad practice.

james.garriss
  • 12,959
  • 7
  • 83
  • 96
kdgregory
  • 38,754
  • 10
  • 77
  • 102
  • 3
    makes perfect sense, should have gone back to the basics. A lot of times patterns become so set in stone that developers tend to take them as Dogma. I have always been told that RuntimeExceptions are a result of a) Programing Errors b) Catastrophic failures from which one cannot recover. In case (a) you want to make sure that everything is fixed before a product goes live and should "never" occur. As for case (b) the user should see a more sanitized message makes perfect sense to catch and process. Now I wonder why at all we need RuntimeExceptions, maybe a topic for another discussion ;-) – VDev Dec 31 '09 at 17:23
  • 2
    Heh, I think it's more of a reason to make *all* exceptions be runtime exceptions. There are a lot of programmers who will catch and ignore checked exceptions, just to make them go away. – kdgregory Dec 31 '09 at 19:37
  • 1
    @LokiAstari don't catch AND rethrow; it will be confusing for debugging, as the same exception might appear twice. Log and display the exception message is acceptable, or log trace and rethrow the exception. Or don't log and rethrow. – Benjamin Marwell Apr 27 '17 at 05:58
  • @BenjaminMarwell it's OK to catch and rethrow, that's called exception chaining. Effective Java book covers this. – mercury0114 Jun 21 '23 at 14:35
  • I meant "don't log and rethrow", Sorry. But reading my comment, you might have guessed so already... – Benjamin Marwell Jun 25 '23 at 12:36
35

Unless you can correct a RuntimeException, you don't want to catch it...

...only true from a developers point of view....

you have to catch all exceptions before they reach up to the UI and make your user sad. This means on the "highest level" you want to catch anything that happend further down. Then you can let the user know there was a problem and at the same time take measures to inform the developers, like sending out alarm mails or whatever...

It is basically considered a data/programming error that could not be forseen, thus you want to improve future releases of the software while at the same time take the user by the hand and move on in a controlled manner...

raoulsson
  • 14,978
  • 11
  • 44
  • 68
17

RuntimeException is intended to be used for programmer errors. As such it should never be caught. There are a few cases where it should be:

  1. you are calling code that comes from a 3rd party where you do not have control over when they throw exception. I would argue that you should do this on a case by case basis and wrap the usage of the 3rd party code within your own classes so you can pass back non-runtime exceptions.

  2. your program cannot crash and leave a stack trace for the user to see. In this case it should go around main and around any threads and event handling code. The program should probably exit when such exception occurs as well.

In your specific case I would have to question why you are having RuntimeExceptions occur in the tests - you should be fixing them instead of working around them.

So you should guarantee that your code only throws RuntimeExceptions when you want to have the program exit. You should only catch RuntimeExceptions when you want to log it and exit. That is what is in line with the intent of RuntimeExceptions.

You can look at this discussion for some other reasons that people give... I personally haven't found a compelling reason in the answers though.

Community
  • 1
  • 1
TofuBeer
  • 60,850
  • 18
  • 118
  • 163
  • 1
    Or 3. you can resolve or workaround the issue at a mid-level before it escapes up the stack tree – tar Aug 21 '15 at 12:39
  • How is a REST service down a programmer error ? – Diego Ramos Mar 20 '22 at 16:46
  • @DiegoRamos it would probably not be. If you provided a wrapper and violated the constraints then it would be. If you didn't provide a wrapper and violated the constraints then maybe, but. I would not do it for that. – TofuBeer Apr 05 '22 at 20:08
10

In my code 99% of my exceptions are derived from runtime_exception.

The reasons I catch exceptions are:

  • Catch Log and Fix problem.
  • Catch Log and Generate a more specific exception and throw
  • Catch Log and rethrow.
  • Catch Log and Kill operation (discard exception)
    • User/request initiated action fails.
      An HTTP request handler for example. I would rather the requested operation die rather than bring the Service down. (Though preferably the handler has enough sense to return a 500 error code.)
    • Test case passed/failed with an exception.
    • All exceptions not in the main thread.
      Allowing exceptions to escape a thread is usually badly documented but usually causes program termination (without stack unwinding).
b4hand
  • 9,550
  • 4
  • 44
  • 49
Martin York
  • 257,169
  • 86
  • 333
  • 562
7

Years ago, we wrote a control system framework and the Agent objects caught runtime exceptions, logged them if they could and continued.

Yes we caught Runtime exceptions including OutOfMemory in our framework code( and forced a GC, and it's surprising how well that kept even quite leaky code running.) We had code that was doing very mathematical things involving the real world; and from time to time a Not-A-Number would get in due to tiny rounding errors and it coped okay with that too.

So in framework / "must not exit" code I think it can be justifiable. And when it works it's pretty cool.

The code was pretty solid, but it ran hardware, and hardware tends to give screwy answers sometimes.

It was designed to run without human intervention for months at a time. It worked extremely well in our tests.

As part of the error recovery code, it could resort to rebooting the entire building using the UPS's ability to turn off in N minutes and turn on in M minutes.

Sometimes hardware faults need to power cycled :)

If I remember, the last resort after an unsuccessful power cycle was it sending an email to it's owners, saying "I tried to fix myself and I can't; the problem is in subsystem XYZ", and included a link to raise a support call back to us.

Sadly the project got canned before it could become self aware :)>

Tim Williscroft
  • 3,705
  • 24
  • 37
5

Personally, I've always been told that you want to catch all RuntimeExceptions; however, you also want to do something about the exception, such as running a failsafe or possibly just informing the user that an error occurred.

The last Java project that I worked on had a similar approach, at the very least, we would log the exception so that if a user called complaining about a bug, we could find out exactly what happened and see where the error occurred.

Edit 1: As kdgregory said, catching and ignoring are two different things, generally, people are opposed to the latter :-)

Topher Fangio
  • 20,372
  • 15
  • 61
  • 94
3

We all know that checked exceptions and RuntimeExceptions are the two categories of exceptions. It is always suggested that we handle (either try-catch or throw) the checked exceptions because they are the programming conditions where unfortunately programmer can not to do anything on its own; Like FileNotFoundException it is not the programmer who puts files on user's drive if program is actually trying to read the file 1.txt which is supposed to be there on f:\ of user with the statements:

File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);

If the file is found it's all ok, but what happens in the other case if the file is not found is that, program crashes down with 0 error from the user. In this scenario programmer did not do anything wrong. This could be a checked exception which must be caught for the program to continue running.

Let me also explain the second scenario with which the concept of RuntimeException will be clear. Consider following code:

int a = {1,2,3,4,5};
System.out.println(a[9]);

This is poor coding which generates the ArrayIndexOutOfBoundsException. Which is an example of RuntimeException. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.

b4hand
  • 9,550
  • 4
  • 44
  • 49
sunya
  • 43
  • 4
3

You catch RuntimeException when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.

b4hand
  • 9,550
  • 4
  • 44
  • 49
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
1

You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of all the tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.

Another common situation is a server; you don’t want to shut down just because one request was malformed in a way you didn't expect. (Unless it’s really, really important to minimize the chances of inconsistent state.)

In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.

One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do after catching it: how your program should continue.

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
1

If a client can reasonably be expected to recover from an exception, make it a checked exception.

If a client cannot do anything to recover from the exception, make it an unchecked exception.

Here's the bottom line guideline.

From Java Docs. Please read this Unchecked Exceptions — The Controversy

VedantK
  • 9,728
  • 7
  • 66
  • 71
  • From the links you sent: `If a client can reasonably be expected to recover from an exception, make it a checked exception` - I don't agree with this, because how can API code throwing an exception possibly know, if a client will be able to recover or not? Maybe the client is some security oriented product, and it can't let any exception propagate, so it will always try to catch and recover. Maybe the other way around. The API doesn't know who the client is in advance. WDYT? – mercury0114 Jun 22 '23 at 07:21