How to handle expired http requests in Svelte? - Stack Overflow

The way I have it set up is a class that handles all the api calls. In this class I keep a map for GET

The way I have it set up is a class that handles all the api calls. In this class I keep a map for GET requests, key is url, value is AbortController.

If a request is being sent and another one of the same type comes before the other has finished, then I call abort() on the prev one and honor the new one.

Problem is that I get many uncaught exceptions on svelte effects when signal is aborted, and adding try/catch everywhere would be a lot of hassle.

Are there better ay to handle this? In React there is reactquery, but I prefer not to use some external library if possible

The way I have it set up is a class that handles all the api calls. In this class I keep a map for GET requests, key is url, value is AbortController.

If a request is being sent and another one of the same type comes before the other has finished, then I call abort() on the prev one and honor the new one.

Problem is that I get many uncaught exceptions on svelte effects when signal is aborted, and adding try/catch everywhere would be a lot of hassle.

Are there better ay to handle this? In React there is reactquery, but I prefer not to use some external library if possible

Share Improve this question asked Mar 24 at 23:13 AlexAlex 66.1k185 gold badges459 silver badges651 bronze badges 1
  • This is very intersting. I have created this issue for the dr-fetch package. I'll implement the feature in a week's time. I usually work these things over the weekends. I know you don't want an external package, but this is not a concern of Svelte. You either write the boilerplate, or you create your own wrapper in the project, or you consume an external package. – José Ramírez Commented Mar 25 at 18:25
Add a comment  | 

3 Answers 3

Reset to default 0

You probably will have to handle each case properly. If you return some unexpected data in the abortion case, the code using it will also likely throw an exception.

So either add try/catch everywhere, or use the errors as values pattern, which I would recommend, since it encourages proper error handling.

In JS you can e.g. return an object with a status property so you get various shapes of objects, depending on what happened, e.g.

{ status: 'ok', data: { /* ... */ } }
{ status: 'aborted' }
{ status: 'network-error', error: /* Error instance */ }
{ status: 'server-error', code: 500 }

In TypeScript these can be typed via a discriminated union, so if you check for a specific status, the flow analysis will recognize what properties exist on the object in that branch.

In you API code you would handle a rejection of the fetch and check the error name for the value 'AbortError', in that case you resolve the request with the value { status: 'aborted' }.

I don't know if this will work for you in practice, and even if it does it might be a bad idea, but you can in $effect() use thePromise.then() instead of await thePromise. Then $effect() will never complain about an uncaught exception from the promise.

However, if no one is listening for when the promise gets rejected, then the web browser will complain when it gets rejected, and you will still end up with a warning in the console (although not from $effect()). But this one you can avoid by adding .catch() callback to the promise (when you create it, or just before it will get rejected) that do nothing (like () => null).

To answer your question: Svelte doesn't provision anything that could help you deal with the exceptions thrown by aborting an HTTP request for your particular case of discarding a previous, unfinished HTTP request in favor of a new one, and I don't see this happening as Svelte is a general-purpose, unopinionated UI framework.

The solution I propose is using my very new fetch wrapper: dr-fetch

Using dr-fetch

This question made me add support for auto-abortable HTTP requests, which is now available in v0.9.0.

Follow the package's quickstart to understand how to set a fetcher object up, then make an abortable fetcher out of the root (base) fetcher. Some code starting at this point:

// root-fetchers.ts
import { DrFetch } from "dr-fetch";

export const rootFetcher = new DrFetch(...); // Etc.  Follow the README.

// Now the abortable fetcher.
export const abortableRootFetcher = rootFetcher.clone().abortable();

That's all you need to do to set the fetcher up. Just use it.

<!-- Autocomplete.svelte -->
<script lang="ts">
  import { abortableRootFetcher } from './root-fetchers.js';
  import type { AutoCompleteItem } from './my-types.js';

  const searchKey = Symbol(); // A symbol is best for an autocomplete component.

  let listItems = $state<AutoCompleteItem[]>([]);

  async function search(searchTerm: string) {
    const response = await abortableRootFetcher
      .for<200, AutoCompleteItem[]>()
      .for<204, undefined>()
      .get(`/my/url?s=${searchTerm}`, { autoAbort: { key: searchKey, delay: 500 }});
    if (!response.aborted) {
      listItems = response.body ?? [];
    }
  }
</script>

<input type="text" oninput={(e) => search(e.currentTarget.value)} />

Explanation

An abortable fetcher object is used because abortable fetchers provide the necessary try..catch block to trap and filter out the exception that is thrown whenever a fetch call is aborted.

A unique symbol is used here so each instance of the AutoComplete component uses a different symbol, so one autocomplete doesn't mess up with the HTTP request of another autocomplete.

When calling DrFetch.get(), we specify the auto-abort key along with a delay in milliseconds. This delay effectively works as debouncing the request during the specified time. Now you don't even need to debounce the call yourself.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744224443a4563936.html

相关推荐

  • How to handle expired http requests in Svelte? - Stack Overflow

    The way I have it set up is a class that handles all the api calls. In this class I keep a map for GET

    9天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信