Chained promises broken when testing due to $exceptionHandler interference #3174
Description
The Promises specification has the following to say about chaining promises:
then
must return a promisepromise2 = promise1.then(onFulfilled, onRejected);
If either
onFulfilled
oronRejected
returns a value that is not a promise, promise2 must be fulfilled with that value.If either
onFulfilled
oronRejected
throws an exception, promise2 must be rejected with the thrown exception as the reason.
However, when using Karma to test a module, I noticed that the following inside the method under test failed:
return $http.post(endpoint, data).then(function(response) {
//return some data from the response
}, function(error) {
var throwable;
//grab some data from the response to create a meaningful rejection reason
throw throwable;
});
When invoking the method as follows, with a mocked HTTP backend to force a failure:
service.do(args).then(function(unused) {
expect(false).toBe(true);//In the absence of a fail() method, use a contradiction
}, function(error) {
expect(error.code).toBe(FAILURE_VAL);
});
Instead of the expectation being met in the onRejected
function, the exception propagates up the stack and fails the test. This is because apparently during tests, the default policy of $exceptionHandler
is rethrow.
I don't understand what business $exceptionHandler has at all being invoked by $q, especially since this behavior violates the Promises/A specification. Exceptions being thrown is a normal and expected part of promise execution.