[whatwg/fetch] A resource timing entry is not created if the end of a non-null response body is not reached and there is no consume body steps (Issue #1813)

Lubrsi created an issue (whatwg/fetch#1813)

### What is the issue with the Fetch Standard?

For example, the given code will not produce a resource timing entry:
```js
fetch("/alwayserror").then(resp => {
    if (!resp.ok) {
        return "status_" + resp.status;
    }
    return resp.text();
}).then(() => {
    console.log(JSON.stringify(performance.getEntriesByType("resource")));
});
```
Where `/alwayserror` is an endpoint which returns an error status code and a response body containing one byte.

In Blink, WebKit and Gecko, they produce a resource timing entry, but they all have a race condition of when it becomes available. In my testing on macOS 15.3.1:
- For WebKit, it's a coin flip if the resource timing entry is available in the promise job reaction for the second `then`
- For Gecko, I had to wait until at least the next task (e.g. a `setTimeout(() => {}, 0`) for the entry to be available.
- In Chrome, I had to wait for at least a 51ms timeout for the resource entry to start appearing, but it's hit and miss if it's available at that timeout.
- Reading the body to the end (e.g. removing the `if (!resp.ok)` path in the above example) produces a resource timing entry straight away in all three, available in the second `then` callback.

On the live web, this is encountered by Cloudflare Turnstile.

This is caused by `processResponseEndOfBody` being called as the flush algorithm when reading the body through a TransformStream in [fetch response handover](https://fetch.spec.whatwg.org/#fetch-finale). If the end of the stream is not reached, flushAlgorithm is not called.

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

Message ID: <whatwg/fetch/issues/1813@github.com>

Received on Wednesday, 5 March 2025 18:18:09 UTC