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

Add error event hander for the body stream even if the body isn't accessed #379

Merged
merged 1 commit into from
Jan 27, 2018

Conversation

MoritzKn
Copy link
Contributor

@MoritzKn MoritzKn commented Dec 9, 2017

Fixes #378

@codecov-io
Copy link

codecov-io commented Dec 9, 2017

Codecov Report

Merging #379 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #379   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           6      6           
  Lines         424    431    +7     
  Branches      133    135    +2     
=====================================
+ Hits          424    431    +7
Impacted Files Coverage Δ
src/body.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a9c76c1...9073ad5. Read the comment docs.

@bitinn
Copy link
Collaborator

bitinn commented Dec 9, 2017

I think this make sense but I am not certain how browser actually handle this. Fetch Spec seems to suggest a different approach (see step 10):

https://fetch.spec.whatwg.org/#http-network-fetch

@MoritzKn
Copy link
Contributor Author

MoritzKn commented Dec 9, 2017

I tested this in firefox and chrome and both seem to behave like I implemented it.
I have no good overview of the fetch spec, could you please explain what you think would be the right behavior.

@bitinn
Copy link
Collaborator

bitinn commented Dec 11, 2017

@MoritzKn Sorry I haven't had time to look deep into browser behavior recently.

Do you happen to have any screenshots or output from browsers? Do they actually reject invalid encoding instead of just returning result without decompression or garbled result?

The last time I checked Fetch doesn't expose this sort of information.

@MoritzKn
Copy link
Contributor Author

Sorry I have no screenshots of the output or anything but I could make some this evening. In my tests with invalid encoding the fetch promise was resolve but the .text() promise was rejected.

@MoritzKn
Copy link
Contributor Author

MoritzKn commented Jan 4, 2018

@bitinn little later then promised, sorry.

Running this code in node:

const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
  if (url.parse(req.url).pathname === '/invalid') {
    res.setHeader('Content-Encoding', 'gzip');
    res.end('not gzip');
    return;
  }

  res.setHeader('Content-Type', 'text/html; charset=utf-8');
  res.end(`
   <!doctype html>
   <title>Test</title>
   <script>
     fetch('http://localhost:12345/invalid')
       .then(result => console.log('simple request is fine', result))
       .catch(error => console.error('error with simple request', error))

     fetch('http://localhost:12345/invalid').then(res => res.text())
       .then(result => console.log('calling .text() is fine', result))
       .catch(error => console.error('error with calling .text()', error))

     fetch('http://localhost:12345/invalid').then(res => res.blob())
       .then(result => console.log('calling .blob() is fine', result))
       .catch(error => console.error('error with calling .blob()', error))
   </script>
  `);
});

server.listen(12345, 'localhost', () => {
  console.log('listening at http://localhost:12345');
});

and opening http://localhost:12345/ in Firefox show this in the console:
image

and this in Chrome:
image

@MoritzKn
Copy link
Contributor Author

MoritzKn commented Jan 4, 2018

The github polyfill however rejects the error directly:
image

I applied the polyfill without the check if fetch is already present.

If I have time this weekend, I will try to look into this further and perhaps file a spec issue. The behavior doesn't seem well defined.

@MoritzKn MoritzKn closed this Jan 4, 2018
@MoritzKn
Copy link
Contributor Author

MoritzKn commented Jan 4, 2018

Accidentally closed

@MoritzKn MoritzKn reopened this Jan 4, 2018
@bitinn
Copy link
Collaborator

bitinn commented Jan 5, 2018

Thx for looking into this and producing a concise test case.

My guess is browsers doesn't consider this an important case to normalize because there will be no break-the-world exceptions.

@TimothyGu
Copy link
Collaborator

Without looking at the current PR, from a spec standpoint this is pretty well defined. Other than parameter validation errors, fetch() will never return a promise that’s rejected. Instead we should have some kind of signaling mechanism to body consumption methods for them to exit early in case some errors have already occurred.

@MoritzKn
Copy link
Contributor Author

MoritzKn commented Jan 7, 2018

@TimothyGu indeed that is what the PR does.

I got around to test this in Safari and Edge too.

Running the above snippet and opening the page in Safari results in these logs:
image

It logs that something went wrong (Failed to load resource: decoding the raw data not possible.) in the console but resolves the promise. .text() simply resolve to an empty string and .blob() and to a zero size blob.

In Edge the behavior is similar to Chrome and Firefox however the .text() call returns a Promise rejected with a TypeError "Body has already been read" which is not the case.
image

Nevertheless I think an uncaught exception that can't be handled and causes the node process to crash isn't desirable in any case.

@MoritzKn
Copy link
Contributor Author

MoritzKn commented Jan 7, 2018

I now also created an issue on the fetch spec: whatwg/fetch#657
For now I think we should go with the behavior implemented in this PR since it's the most in line with browser behavior and makes the most sense in my opinion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants