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

DOMException [AbortError]: This operation was aborted #24

Closed
jasperzs opened this issue May 13, 2023 · 7 comments
Closed

DOMException [AbortError]: This operation was aborted #24

jasperzs opened this issue May 13, 2023 · 7 comments

Comments

@jasperzs
Copy link

jasperzs commented May 13, 2023

Hi,

Thanks for putting up this awesome library! I recently started to use Apollo client to hit our graphQL api using Next.js app router. Currently, after a (SSR/SSG with export const revalidate = xxx) page is first loaded, then subsequently refreshing it in browser gives DOMException [AbortError]: This operation was aborted. From an old post while googling, I was able to make this error disappear by configuring an abortController in the httpLink, but my gut feeling tells me this probably is not the right way to address this problem.

Could you please shed some light on how to solve this the right way? Thank you!
image

My apollo client configuration is this:
image

@phryneas
Copy link
Member

Could you create a minimal reproduction for this issue? I'd need to see that myself to look into that.

@jasperzs
Copy link
Author

jasperzs commented May 29, 2023

@phryneas I found out it's this line that caused the above DOM Exception AbortError. Any idea why this line is needed?
https://github.com/apollographql/apollo-client/blob/249076fd908c79350077369961ea8e78fb06d862/src/link/http/createHttpLink.ts#L201

Currently, to avoid this abortController call to trigger the AbortError, I passed my own signal to fetchOptions, but I don't know what side effect will this incur? Will it affect any cleanup action that apollo client does?
https://github.com/apollographql/apollo-client/blob/249076fd908c79350077369961ea8e78fb06d862/src/link/http/createHttpLink.ts#L123

And in the polls-demo example, you can reproduce this issue by removing export const dynamic and replace it with export const revalidate = 5.
https://github.com/apollographql/apollo-client-nextjs/blob/main/examples/polls-demo/app/rsc/page.tsx#L6

@phryneas
Copy link
Member

I've done some digging here.

Essentially: this is the doing of Next.js, and there is probably nothing we can do about it.

You can find the related code here:
https://github.com/vercel/next.js/blob/05f6de10869021dbb6124e174778e2108c9b4e8e/packages/next/src/server/lib/patch-fetch.ts#L231-L233

Here, Next.js calls fetch with the AbortSignal we pass in, and then it doesn't re-throw errors, but just console.logs and swallows then.

Now, we make every request with an AbortSignal and as a general cleanup, we cancel that signal at the end. Any errors that would be thrown by that are caught by us, and discarded. We can't catch & discard this AbortError, because Next.js handles it on their own. And honestly, in a completely irresponsible fashion. This could be any kind of error, and it will never surface.

Your workaround essentially means that you take control over the fetch request lifetime - we cannot stop outgoing requests anymore, and that is your job now.

Honestly, at this point I don't really know what we can do here :/
I'll have to discuss this internally.

Maybe you can also open an issue over at the Next repo?

@t-zander
Copy link

For me it looks like this revalidate option is not taken into account at all.
This doesn't work

const { data } = await getClient().query({
      query,
      context: {
        fetchOptions: {
          next: { revalidate: 5 },
        },
      },
    });

and

export const revalidate = 5;

doesn't work too.

I am taking this directly from this resource
https://www.apollographql.com/blog/apollo-client/next-js/how-to-use-apollo-client-with-next-js-13/#revalidating-graphql-requests

If I do this:

const { data } = await fetch(
    "https://main--time-pav6zq.apollographos.net/graphql",
    {
      method: "POST",
      body: JSON.stringify({
        query: '{ now(id: "1") }',
      }),
      headers: {
        "Content-Type": "application/json",
      },
      next: { revalidate: 10 },
    }
  ).then((res) => res.json());

it works perfectly fine

@phryneas
Copy link
Member

phryneas commented Jun 16, 2023

It's very possible that the fact that we cancel our AbortController after the request, and they just blindly reuse that AbortController means that their revalidation request never happens. :/

That's why you don't mess with fetch :(

@phryneas
Copy link
Member

I believe this has been fixed quite a while ago in HttpLink, so I'm closing this here.

Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

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

No branches or pull requests

3 participants