[w3c/ServiceWorker] clarify behaviour of `AbortSignal` in `FetchEvent::respondWith` (Issue #1662)

Currently, the ServiceWorker specification does not mention (anywhere) `AbortSignal` or describe behaviour when `AbortSignal` is used. The most pertinent area of the ServiceWorker spec is [`FetchEvent::respondWith(r)`](https://w3c.github.io/ServiceWorker/#dom-fetchevent-respondwith).

In some scenarios, it may be desirable for a ServiceWorker to abort a request; for example, when the ServiceWorker intercepts a request to a protected resource and no authentication is available.

Chrome and Firefox both trigger a NetworkError when a ServiceWorker uses AbortSignal to cancel a request. This changes upstream event handling: If it were handled "correctly", the promise would resolve (as it does normally, when the client itself aborts the request). 

**Cons** of a processing AbortSignal as a NetworkError:

* Misinformation: The user is mislead into thinking an actual network problem has occurred or there's an issue with their environment.
* Contravention of the Principle of Least Knowledge: The user must know ServiceWorker's AbortSignal is a special snowflake.
* Specific handling: The user must differentiate between a real and fake NetworkError.

**Pros** of a processing AbortSignal as normal:

* Accuracy: It's what actually happened.
  * Adherent to the Principle of Least Knowledge: A custom reason can be provided.
* Familiarity: The user will already be familiar with handling.
* No specific handling: The user does _not_ need to divine between a real and fake NetworkError.

A simple code sample of this is available here: https://codesandbox.io/s/hidden-currying-n4fttq but note it does not actually work because CodeSandbox already has another ServiceWorker running (if you run that code elsewhere, it does repro the issue).

A real-world example is available here: https://github.com/JakobJingleheimer/webapp-auth-via-serviceworker.

A possible alternative, which may be outside the scope of this group, is to allow supplying an AbortSignal directly to the `Response()` constructor and/or making the one it already has mutable. IMHO this would be a more ideal solution as it's straightforward and requires less code:

```js
const ctrl = new AbortController();

event.respondWith(fetch(event.request, {
  signal: ctrl.signal,
}));

ctrl.abort('doom');
```

vs

```js
const ctrl = new AbortController();
const response = new Response(undefined, { signal: ctrl.signal });

event.respondWith(response);

ctrl.abort('doom');
```

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1662
You are receiving this because you are subscribed to this thread.

Message ID: <w3c/ServiceWorker/issues/1662@github.com>

Received on Tuesday, 15 November 2022 09:32:58 UTC