1

I've coded a method with a catch-all handler, but I need to rethrow the exception as if it were unhandled, so that a caller (much) further up the call stack can handle it. The trivial way to do this is simply:

try {
   ...
} catch (Exception ex) {
   // do something here...
   // and rethrow
   throw ex;
}

But the problem is that, because of the throw statement, Java requires this method to declare itself as throws Exception, which in turn, requires all the callers to handle the exception or declare themselves as throws Exception. And so on up the call chain...

Is there any simple way to rethrow the exception as if the current method did not handle it?

adelphus
  • 10,116
  • 5
  • 36
  • 46
  • Exactly like this. If you didn't have the try/catch here, your method would need to `throws Exception` (or, at least, `throws` the types of exceptions actually thrown in the method calls in the `try` block). – Andy Turner Feb 08 '16 at 17:05
  • 1
    `catch(RuntimeException ex)`. Unless your code throws a checked exception, then you will want a handler for `RuntimeException` and another for the the specific checked exceptions - wrap in `RuntimeException` and rethrow. – Boris the Spider Feb 08 '16 at 17:09
  • 1
    "with a catch-all handler" is rarely a good idea. Why are you doing this? – Raedwald Feb 08 '16 at 17:10
  • Just in case: you know about `finally`, right? – user2357112 Feb 08 '16 at 17:12
  • @Raedwald I need this for a scripting engine which itself could throw anything. I need to intercept the exception to add additional information, but then let other libraries handle it. – adelphus Feb 08 '16 at 17:13
  • 1
    @adelphus: Just how inclusive is "anything"? What do the methods inside the `try` declare for `throws`? – user2357112 Feb 08 '16 at 17:15
  • @user2357112 yes - finally would be ideal, but I need access to the exception which I don't think is possible from a finally block – adelphus Feb 08 '16 at 17:16
  • @user2357112 The exceptions can be thrown by a native component. Hence the catch-all, because there is no declared list of throwable types. – adelphus Feb 08 '16 at 17:19
  • Possible duplicate of [Why is the Catch(Exception) almost always a bad Idea?](http://stackoverflow.com/questions/2416316/why-is-the-catchexception-almost-always-a-bad-idea) – Raedwald Feb 08 '16 at 17:22
  • @adelphus: Well, if you really could be propagating any exception type whatsoever out of there, then you should declare `throws Exception`. The catch-all `catch` has nothing to do with it; you should declare `throws Exception` even if you didn't have the `catch`. – user2357112 Feb 08 '16 at 17:22

2 Answers2

3

You have exactly two options with (checked) exceptions:

  1. Handle them in the method via a try/catch (which may include rethrowing as a different exception type)
  2. Declare that the method throws the exception.

If you want to rethrow the exception as if this method did not catch it, your only option is 2.

Note: you only want to catch (Exception e) if a method in the try block actually throws Exception. Otherwise, catch the specific exception types.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • I would do 2., but there's a massive call chain dependant on this method which would, in turn, require several hundred methods to all declare themselves as `throws Exception`. Not my idea of fun. – adelphus Feb 08 '16 at 17:29
  • 2
    @adelphus if that's what those method _do_ (i.e. throw an exception), then that's what they **have to** declare they do. – Boris the Spider Feb 08 '16 at 17:34
  • @BoristheSpider ...unless the method is native. In which case, it doesn't have to declare anything and can throw anything. – adelphus Feb 08 '16 at 17:46
  • @adelphus my point was more from the API side than Java's requirements. There is in fact to requirement whatsoever for a method to declare that it throws a checked exception or to handle one when it occurs. But I know, from experience, that methods that randomly and without warning blow up make programmers somewhat...unhappy. So I would suggest that you 1) create an `AdelphusException` 2) wrap anything coming from the native method in one and 3) declare that your API throws them. – Boris the Spider Feb 08 '16 at 17:49
2

You could do what @radoh has said and just wrap into a RuntimeException, but one downside of this is your stacktrace is now polluted and will show the offending line to be where you declare throw new RuntimeException(ex).

An alternative is to use Lomboks SneakyThrows mechanism, like this:

public static void main(String[] args) {
    methodWithException();
}

private static void methodWithException() {
    try {
        throw new Exception("Hello");
    } catch (Exception e) {
        Lombok.sneakyThrow(e);
    }
}

Your stacktrace will remain intact, but you no longer need to declare throws Exception.

It's worth reading the documentation on why you should/shouldn't do this

tddmonkey
  • 20,798
  • 10
  • 58
  • 67
  • The sneakyThrow looks like exactly what I want - thanks. And yes, I know it's bad. I feel evil, but my other alternative is to code a jni library which throws without the Java compiler checking it. Not nice. – adelphus Feb 08 '16 at 17:23