milan
milan

Reputation: 2515

performing clean up and passing the exception to the caller

I need to do some initialization and clean it up in case of any exception. I'd still like the exception to be passed to the caller. The problem is I now have to declare this method as throws Throwable and then I have to explicitly handle this throwable in the caller, just as if all procedures don't throw Throwables implicitly already. Stupid isn't it?


try {
  init_step1();
  init_step2();
}
catch (Throwable th) {
  clean();
  throw th;
}

Upvotes: 0

Views: 226

Answers (3)

Peter Lawrey
Peter Lawrey

Reputation: 533530

@Jon Skeet's solution is the cleanest. Another solution which may interest you.

try {
    // Stuff here
} catch(Throwable t) {
    clean(t);
    // bypasses the compiler check
    Thread.currentThread().stop(t); 
}

I would only suggest using this approach if you needed to know the exception thrown. e.g. For resources I have which are closable, I record the exception which triggered their close. This way if I try to use the resource and it is closed I can see why it is closed.

private void checkClosed() {
    if (closed)
        throw new IllegalStateException("Closed", reasonClosed);
}

Upvotes: 0

Mauricio
Mauricio

Reputation: 5853

Stupid is fighting against checked exceptions. You have to throw something different if you don't want to require every caller to handle it. just throw a RuntimeException

public void myMethod() throws RuntimeException {
    try {
      init_step1();
      init_step2();
    }
    catch (Throwable th) {
        clean();
        throw new RuntimeException(th);
    }
}

why do you catch Throwable in first place anyway? init_step1() and init_step2() doesn't throw an exception?

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500785

One way of doing this is to perform the cleanup in a finally block instead, noticing whether there's been an exception by whether you actually got to the end of the try block or not:

boolean success = false;
try {
    // Stuff here
    success = true;
} finally {
    if (!success) {
        clean();
    }
}

Upvotes: 1

Related Questions