Re: [whatwg/fetch] Add abort reason to abort fetch (PR #1343)

I think the cleanest way to handle this is making `Request` as a whole `[Transferable]`:
* `Request.signal` would be transferred using `AbortSignal`'s transfer steps.
* `Request.body` would be transferred using `ReadableStream`'s transfer steps.

To transfer an `AbortSignal`, we could use some sort of cross-thread message channel. For example, we could construct a `MessageChannel`, attach an abort algorithm to send a message containing the abort reason through one end, and then call "signal abort" with that reason when we receive it on the other end. This is similar to how we currently transfer streams. (And, also similar to streams, we'll have to be careful around "double-transferring" an `AbortSignal`. 😛)

Making `Request` transferable also allows us to clear up some vagueness around how we pass streams through service workers:
* Right now, [Service Worker's handle fetch](https://w3c.github.io/ServiceWorker/#handle-fetch) says:
    > 24.3.2 Let _requestObject_ be a new `Request` object associated with _request_ and a new associated `Headers` object whose guard is `"immutable"`.

    However, _request_'s body may be a `ReadableStream` created in a different realm. It's never specified how this stream should be accessed from within the _workerRealm_. Really, we should *transfer* the entire `Request` to the worker's realm, including its signal and body.

* When [Fetch's HTTP fetch](https://fetch.spec.whatwg.org/commit-snapshots/09acae88ed9e16b842b20b3d464da22f78443367/#http-fetch) receives a non-null response from the service worker (in step 5.5), it should transfer it from the worker's realm to the current realm.

---

> But somehow it seems worse to end up with an empty object as an abort reason in fetch. So I have a preference for censoring it to an `AbortError` on transfer in fetch. I don't know what that would look like in standards language.

I would find it weird if transferring `Request` and then accessing `.signal` would behave different from transferring `Request.signal` directly. 😕

I guess we could *not* make `Request` and `AbortSignal` transferable from user-land code, and only provide dedicated algorithms to "transfer a request" and to "transfer-receive a request". Then we could do some Fetch-specific censoring in there.

> I guess when either serialization or deserialization ends up throwing we can pass on undefined and then do the undefined -> new "AbortError" DOMException trick. It would be nice if this was aligned with Streams though.

It won't necessarily throw. You may still get back an empty object, because it's merely serializing all the own properties.
```javascript
class MyError {
  get message() {
    return "Oops!";
  }
}
const original = new MyError();
original.message; // -> "Oops!"
const clone = structuredClone(original);
clone.message; // -> undefined
```

-- 
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/fetch/pull/1343#issuecomment-956141639

Received on Monday, 1 November 2021 11:11:04 UTC