Hi Jerome, > > } catch (InvocationTargetException e) { > > if (e.getCause() instanceof Error) { > > throw (Error) e.getCause(); > > } else { > > getLogger() [...] > > } > I spoke too fast, we should also consider RuntimeExceptions: > catch(InvocationTargetException e){ > if (e.getCause() instanceof Error > || e.getCause() instanceof RuntimeException) { > throw (Error) e.getCause(); > } > getLogger().... > }
This solution doesn't work because if the cause is a RuntimeException, we can't cast it to an Error (doh!). And if we rethrow it as a RuntimeException, it'll get caught by the catch(Exception e) block of the enclosing try block. So, the solution is to throw a RuntimeException from the inner try blok, and let it bubble up from the outer try block: public Resource createResource(Request request, Response response) { Resource result = null; try { ... try { } catch(InvocationTargetException e){ if (e.getCause() instanceof Error){ throw (Error) e.getCause(); } if ( e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } getLogger()... } } catch (RuntimeException e){ // Let unchecked exceptions bubble up throw e; } }catch (Exception e) { getLogger()... } } return result; } In short: we make sure we let all unchecked exceptions (errors & runtime) flow through the method, while all checked ones (Exceptions that are not runtime) are trapped and logged. We should also document the fact that Resource constructors should never throw checked exceptions. -Vincent.