Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix xhr.assertSuccess promise #3737

Merged
merged 2 commits into from
Jun 23, 2016
Merged

Conversation

mkhatib
Copy link
Contributor

@mkhatib mkhatib commented Jun 23, 2016

The else part is obvious. What might not be obvious is the test change. @dvoytenko I dropped (changed actually) the test of the previous return a resolved promise issue inside the constructor of the promise, this doesn't actually to have the effect that we thought it would. Tried it with a snippet like the following:

function myfunc() { 
  return new Promise((resolve, reject)  => {
    return Promise.resolve();
  });
}

myfunc().then(() => console.log('I will never be resolved so I will not log...'));

I am not sure if I am still missing the issue with the previous return statement - if I am can you write a small snippet (like the above) that could show the problem? Probably will help me understand it better.

@dvoytenko
Copy link
Contributor

LGTM to the PR - this is definitely a must fix thing (may need to interrupt canary to pick it up). Find me to discuss the question offline.

mockXhr.status = 500;
mockXhr.responseText = '{"a": "hello"}';
mockXhr.headers['Content-Type'] = 'application/json';
mockXhr.getResponseHeader = () => 'application/json';
const promise = assertSuccess(
createResponseInstance('{"a": 2}', mockXhr));
promise.should.be.rejected;
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the issue that you're not using .should.eventually.be.rejected? Or, you could return the promise with a flip-flop:

return assertSuccess(createResponseInstance('{"a": 2}', mockXhr)).then(() => {
  throw new Error('should never reach this'); // This makes a resolved promise blow up the tests
}, (err) => {
  return; // this makes the rejected promise pass the tests
});

Importantly, this won't hide a never resolving promise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tested with eventually.be.rejected that wasn't the issue. The initial issue we thought might happen (on a previous PR #3669) is that returning the already resolved promise returned from response.json() inside the new Promise constructor would actually resolve the promise instead of actually the intended behavior of rejecting it. This doesn't see true that's why this test no longer needed/valid.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not seeing a return? We did immediately resolve when there was a JSON error response, which we definitely should have caught.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that was previously, we added that test to catch that case and then removed the return statement.

We did immediately resolve when there was a JSON error response, which we definitely should have caught.

Yes the edit to this test makes sure we catch that.

@jridgewell
Copy link
Contributor

PR won't let me comment on the correct line. On L361, there's no need to create another promise instance (chaining a #catch), just pass the onRejected as the second param of the #then:

response.json().then(json => {
  err.responseJson = json;
  reject(err);
}, () => {
  reject(err);
});

@mkhatib
Copy link
Contributor Author

mkhatib commented Jun 23, 2016

Didn't realize chaining .catch creates another instance of a promise. Is passing onRejected just more efficient to do than chaining then?

@jridgewell
Copy link
Contributor

jridgewell commented Jun 23, 2016

Is passing onRejected just more efficient to do than chaining then?

It avoids another Promise instance and runs in the same tick.

@mkhatib
Copy link
Contributor Author

mkhatib commented Jun 23, 2016

Done.

@jridgewell
Copy link
Contributor

LGTM.

@zhouyx zhouyx merged commit d6ed64b into ampproject:master Jun 23, 2016
@mkhatib mkhatib deleted the fix-xhr-promise branch June 23, 2016 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants