urql-graphql / urql

The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
https://urql.dev/goto/docs
MIT License
8.61k stars 450 forks source link

DOMException: The user aborted a request error thrown when reading cloned response #3212

Closed kgpax closed 1 year ago

kgpax commented 1 year ago

Describe the bug

I'll start by saying I'm not 100% sure that this is a bug, but rather that it is behaviour we are seeing which may not be intentional on urql's part.

We are using urql for our GQL client, and in one production instance of our code a 3rd party script is overwriting the window.fetch function, causing it to re-read a cloned version of the response so that it can scrape the content and do some stuff. We are not in control of what this script does, but conceptually it is this:

var originalFetch=window.fetch;
window.fetch = function() {
  var fetch = originalFetch.apply(this, arguments);
  fetch.then(function(Response) {
    Response = Response.clone();
    return Response.text(); // perform another read of the response, via a cloned response object
  }).then(function(responseBody) {
    someCallbackWhichParsesTheResponseBody(responseBody);
  });
  return fetch;
}

(I'm not advocating the above logic; it is just what presents this issue)

Bearing in mind that urql will likely be doing a response.json() (or similar) read of the response stream, it seems that the act of "re-reading" the response (via the clone) triggers the above error. My suspicion is that this relates to the behaviour of aborting in-flight requests which have a newer request triggered, although in this case, only one request is actually issued.... it is just being "read" twice.

Is the fact that the The User aborted a request error is thrown in this scenario valid, or is it something that should not happen?

Reproduction

https://codesandbox.io/s/loving-carlos-js83g6

Urql version

v4.0.0

Validations

kitten commented 1 year ago

This pretty simply looks like your script there isn't respecting that fetch can throw and hence any error will show up as uncaught, which is correct behaviour by the browser. Specifically, when a request is aborted this may lead to an AbortError being thrown. At least, I'm pretty sure that's what's going on.

However, either way, since your error lies in your third-party script, it's not a bug in urql, and not something we can fix or take responsibility for 😅

Also, please upgrade before submitting issues. Your sandbox is using an outdated version and CodeSandbox is likely not resolving the latest version of @urql/core. Specifically, you'll likely want to have this fix so the error that's being caused isn't rethrown :v: https://github.com/urql-graphql/urql/blob/main/packages/core/CHANGELOG.md#patch-changes-4

kgpax commented 1 year ago

Cheers. Seems like Codesandbox only goes up to 4.0.0 🤔 but I'll try your suggestion in a local toy project.

Thanks for the quick reply.

kitten commented 1 year ago

Closing due to inactivity :v: