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

Implement timeout for Apollo Client #429

Open
lughino opened this issue Mar 11, 2024 · 3 comments
Open

Implement timeout for Apollo Client #429

lughino opened this issue Mar 11, 2024 · 3 comments
Labels
🔗 apollo-link Feature requests related to Apollo Link behavior

Comments

@lughino
Copy link

lughino commented Mar 11, 2024

Currently there is no timeout mechanism in Apollo Client. The only way to achieve that is to create a custom link with the logic to timeout and cancel the inflight request.
Considering that Apollo uses the fetch interface, I feel this should be made available directly from the framework, and not rely on custom logic.
Implement this is straightforward as we can leverage the AbortSignal.timeout:

async function loadPosts() {
  try {
    const response = await fetch('/posts', {
      signal: AbortSignal.timeout(5000)
    });
    const posts = await response.json();

    return posts;
  } catch (error) {
    // Timeouts if the request takes longer than 5 seconds
    console.log(error.name === 'AbortError');
    // handle error
  }
}

We could then be able to set a global timeout and override it on query basis passing a timeout option

@jerelmiller
Copy link
Member

Hey @lughino 👋

Thanks for the request! I'd like to poke at this a little bit to understand your thinking here.

HttpLink has the ability to set options on the fetch call via context.fetchOptions. With something like the setContext link, this can be used to set a timeout signal if not already provided in context as such:

setContext((_, previousContext) => ({
  fetchOptions: {
    signal: previousContext.fetchOptions?.signal || AbortSignal.timeout(5000)
  }
})

You can override this per-query using context:

useQuery(query, {
  context: {
    fetchOptions: { signal: AbortSignal.timeout(10_000) }
  }
});

HttpLink will use this signal if its provided.


Given the above, I'd like to understand how you envision something more integrated and what shortcomings there might be of the solution I posted above. I personally don't feel like this is a lot of code, and I'm not sure if something more integrated would be much more elegant. If we can avoid the bundle size in the library by using existing functionality, that would be ideal.

I may be shortsighted here, so please let me know what I'm missing! Thanks again for the request!

@jerelmiller jerelmiller added the 🔗 apollo-link Feature requests related to Apollo Link behavior label Mar 11, 2024
@lughino
Copy link
Author

lughino commented Mar 11, 2024

Hi @jerelmiller ,
Thanks for the quick reply!

Yes, it is possible to use the context in this way. I did not think of this solution, as my solution was to create a custom link with the timeout logic.
I would argue that the API exposed in this way is a bit obscure and not immediate. The link could handle this basic scenario directly, offering an explicit timeout option that can be looked from the interface of the hooks with an immediate understanding of the functionality.
I believe adding this would likely add no more than few bytes to the library bundle

@jerelmiller
Copy link
Member

I would argue that the API exposed in this way is a bit obscure and not immediate.

That's fair, but I'd consider solving this with documentation first 🙂. If the above solution were a ton of code, I could definitely see a compelling reason to include it.

If you want to provide something more simple/out-of-the-box, would a third-party package be an option? If you're interested in publishing a package, we'd be happy to list it in our community links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔗 apollo-link Feature requests related to Apollo Link behavior
Projects
None yet
Development

No branches or pull requests

2 participants