- From: Gil Pedersen <notifications@github.com>
- Date: Sun, 28 Nov 2021 05:04:28 -0800
- To: whatwg/dom <dom@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/dom/issues/1033/981082182@github.com>
@domenic Checking the error is not sufficient if you don't control the `signal`. When you expose an API that takes a `signal`, you no longer control it. Eg. for this, you now[^1] need to check the `signal` to safely drop retries:
```js
export async function retryableGetBlob(url, { signal, retries } = {}) {
try {
const res = await fetch(url, { signal });
if (res.status !== 200 && res.status !== 204) {
throw new BadResponseError(res.status);
}
return await res.blob();
}
catch (err) {
if (signal?.aborted) {
throw signal.reason !== undefined ? signal.reason : new DOMException('User abort', 'AbortError');
}
if (!retries || isFatalError(err)) {
recordUpstreamFailureMetric(err);
throw err;
}
// retry on soft errors
return retryableGetJson(url, { signal, retries: retries - 1 });
}
}
```
Here you don't want to call `recordUpstreamFailureMetric()` on API caller aborts, no matter how it is aborted. Additionally without the guard, an `ac.abort(/* <something that looks like a soft error> */)` would repeatedly call `fetch` with an aborted `signal` until `retries === 0`.
This is probably how it should be, and I like the power that `signal.reason` provides the `AbortController` owner. It just means that API providers will need to check `signal.aborted` *before* checking the error when calling an API with a forwarded `signal`. Similar to how API providers need to check `signal.aborted` after calls to async methods that don't support cancellations.
[^1]: once `signal.reason` is used in fetch
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1033#issuecomment-981082182
Received on Sunday, 28 November 2021 13:04:41 UTC