Add Uncaught Exception Handler
saturnism opened this issue · comments
In DeferredManager, add ability to register a catch all uncaught exception handler. In case any Throwable was uncaught, pass it to the handler.
Applications should always try to handle known exceptions in the fail() handler explicitly. This is as a last-resort fallback.
By default, the handler will log the uncaught exception.
Related to #54
As I understand it, exceptions get recorded as the rejected value when the body of the promise throws an exception. This exception is sent to the FailureCallback if such callback is registered. This means handling exceptions that may occur during the task part of a promise is already managed.
What's missing is the case when unchecked exceptions occur during the following callbacks: then
, done
, fail
, always
. To be honest I think it's the job of the developer to handle these potential problems, as he/she already has to handle checked exceptions within these callbacks.
Adding another exception handler to Promise
may look a bit odd, for example
deferredManager.when(() -> /* do the work */)
.done(result -> throw new RuntimeException("boom!"))
.fail(result -> {
// handle exception that appeared in the _when_ block
throw new IllegalStateException("oops"); })
.always((state, result, throwable) -> {
// well, guess we can throw too
throw new IlegalArgumentException("Objection!"); })
.exception(state, throwable -> {
// this is the new callback capable of
// handling exceptions thrown by
// then, done, fail, always
});
What happens if an exception is thrown during the exception
block now? It's all turtles the way down.
Also, the always
block is called regardless of how done
and fail
where handled. In this particular case the exception
block should be called twice: one for the exception thrown by done
/fail
(depending on success or failure) and always
, making this callback the only one that can be called more than once whereas the others can be called just one time.
Fixed with #131