Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngResource): do not eat exceptions in success callback #15628

Closed
wants to merge 4 commits into from

Conversation

kylewuolle
Copy link
Contributor

@kylewuolle kylewuolle commented Jan 19, 2017

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix

What is the current behavior? (You can also link to an open issue here)
Addresses bug identified in #15624.

No error message is output in the console:

var User = $resource('users/:id', {id: '@id'});
var user User.get({id: 123}, function (res) {
    y  = x + z; // this line not log any exception on the console
}, function () {
    console.log(arguments);
});

Error message is output in the console:

var User = $resource('users/:id', {id: '@id'});
var user User.get({id: 123}, function (res) {
    y  = x + z; // and this log the exception in the console
});

What is the new behavior (if this is a feature change)?
Now any exceptions thrown in the success callback will be thrown and not eaten.

Does this PR introduce a breaking change?
No

Please check if the PR fulfills these requirements

Other information:

move the promise catch noop call inside of error callback handler so that errors inside of the success callback are not eaten
added two tests to prove functionality
No breaking changes
Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks good. I've left a comment regarding the tests.

@@ -1978,4 +1978,39 @@ describe('configuring `cancellable` on the provider', function() {
expect(creditCard3.$cancelRequest).toBeDefined();
});
});

describe('exception handling in callbacks', function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests should be incorporated into the errors block. Also, can you add tests for all 4 combinations (no errorCallback/no responseErrorInterceptor, no errorCallback/yes responseErrorInterceptor, yes errorCallback/no responseErrorInterceptor, yes errorCallback/yes responseErrorInterceptor).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks I made the changes requested!

@kylewuolle
Copy link
Contributor Author

Thanks I made the changes


it('should throw exception in success callback when error callback provided and no responseErrorInterceptor', function() {
$httpBackend.expect('GET', '/CreditCard/123').respond({ id: 123, number: '9876' });
var CreditCard = $resource('/CreditCard/:id:verb', { id: '@id.key' });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the unnecessary bits (here and below). E.g.:

$httpBackend.expect('GET', '/CreditCard/123').respond(null);
var CreditCard = $resource('/CreditCard/:id');

@@ -1709,6 +1709,79 @@ describe('handling rejections', function() {
expect($exceptionHandler.errors[0]).toMatch(/^Possibly unhandled rejection/);
})
);


it('should throw exception in success callback when error callback provided and no responseErrorInterceptor', function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the tests descriptions to something like:

should not swallow exception in success callback...

var CreditCard = $resource('/CreditCard/:id:verb', { id: '@id.key' }, {
'get': {
method: 'GET',
interceptor: { responseError: function() { return $q.reject({}); } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a non-rejecting interceptor.

var CreditCard = $resource('/CreditCard/:id:verb', { id: '@id.key' }, {
'get': {
method: 'GET',
interceptor: { responseError: function() { return $q.reject({}); } }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a non-rejecting interceptor.

@kylewuolle
Copy link
Contributor Author

Thanks I fixed up the tests etc

@gkalpak
Copy link
Member

gkalpak commented Feb 4, 2017

LGTM 👍
I'll clean up the tests a bit more (e.g. remove unused default params ({ id: '@id.key' })) and merge.

@gkalpak gkalpak closed this in edfb691 Feb 4, 2017
gkalpak pushed a commit that referenced this pull request Feb 4, 2017
Previously, errors thrown inside the `success` callback would be swallowed by a
noop `catch()` handler. The `catch()` handler was added in order to avoid an
unnecessary "Possibly Unhandled Rejection" error, in case the user provided an
`error` callback (which would handle request errors).

The handler was added too "eagrly" and as a result would swallow errors thrown
in the `success` callback, despite the fact that those errors would _not_ be
handled by the `error` callback.

This commit fixes this, by adding the `catch()` handler "lazily", only when it
is certain that a rejection will be handled by the `error` callback.

Fixes #15624

Closes #15628
ellimist pushed a commit to ellimist/angular.js that referenced this pull request Mar 15, 2017
Previously, errors thrown inside the `success` callback would be swallowed by a
noop `catch()` handler. The `catch()` handler was added in order to avoid an
unnecessary "Possibly Unhandled Rejection" error, in case the user provided an
`error` callback (which would handle request errors).

The handler was added too "eagrly" and as a result would swallow errors thrown
in the `success` callback, despite the fact that those errors would _not_ be
handled by the `error` callback.

This commit fixes this, by adding the `catch()` handler "lazily", only when it
is certain that a rejection will be handled by the `error` callback.

Fixes angular#15624

Closes angular#15628
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants