mdn / content

The content behind MDN Web Docs
https://developer.mozilla.org
Other
8.99k stars 22.44k forks source link

Issue with "Response.json()": Possible exceptions not documented #13208

Closed ilyvion closed 1 week ago

ilyvion commented 2 years ago

MDN URL: https://developer.mozilla.org/en-US/docs/Web/API/Response/json

What information was incorrect, unhelpful, or incomplete?

This function can raise exceptions, but these are not documented. Try using it on a response that is not actually JSON, e.g.

Specific section or headline?

Exceptions

What did you expect to see?

The list of possible exceptions and their causes. See the fetch documentation for an example of a function that documents its exceptions well.

MDN Content page report details * Folder: `en-us/web/api/response/json` * MDN URL: https://developer.mozilla.org/en-US/docs/Web/API/Response/json * GitHub URL: https://github.com/mdn/content/blob/main/files/en-us/web/api/response/json/index.md * Last commit: https://github.com/mdn/content/commit/93ae23dec42bba9d71d6f1ed45668d8d26847e9c * Document last modified: 2022-02-18T09:26:54.000Z
hamishwillee commented 2 years ago

The other response attributes are also missing exceptions - e.g. body, formData, etc - see https://fetch.spec.whatwg.org/#ref-for-dom-body-json%E2%91%A0

The spec looks a bit confusing. It looks like TypeError if the body of the response is unusable. But that maps to "is non-null and its body’s stream is disturbed or locked." - but then it isn't clear what that means - i.e. how code could have ended up in that state and what it means a user is doing wrong.

On top of that it looks like there would also be SyntaxError from parsing the JSON from the body back into a Javascript object, - like this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#exceptions

Anyone got any real experience on this?

wbamberg commented 1 year ago

The other response attributes are also missing exceptions - e.g. body, formData, etc - see https://fetch.spec.whatwg.org/#ref-for-dom-body-json%E2%91%A0

The spec looks a bit confusing. It looks like TypeError if the body of the response is unusable. But that maps to "is non-null and its body’s stream is disturbed or locked." - but then it isn't clear what that means - i.e. how code could have ended up in that state and what it means a user is doing wrong.

...

Anyone got any real experience on this?

No real experience, but I believe "disturbed or locked" is mostly to do with the fact that a response body can only be consumed once, because it's a stream. So for example, if a request is intercepted in a service worker which then reads the response, then sends the response back to the main thread, then I think the main thread will get an error like this when it tries to read the response.

The spec for "disturbed":

This indicates whether the stream has ever been read from or canceled.

The spec for "locked" is a bit more cryptic, but I believe the idea is that a stream is locked when you attach a reader to it (for example in https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultReader/ReadableStreamDefaultReader). The point being that once you have a reader, you want to ensure that noone else can consume this stream, otherwise you wouldn't know whether you'd actually be able to read from it or not - effectively it prevents race conditions.

To avoid these issues, you should use Response.clone() if you want to do something with a response but have someone else do something with it later. The classic example here is where a service worker wants to cache a response but then return it to the main app thread. See for example the code sample in https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Offline_and_background_operation#offline_operation.

Since this is behavior is a bit complex to explain and will be common across all the places you can consume a response body (including blob(), formData(), text() etc), I think we should explain this somewhere in our Fetch documentation, and link to it from the "Exceptions" sections for each of these APIs.