fix(api): Response.finished() throws when target closes (#20453)

This commit is contained in:
Dmitry Gozman 2023-01-27 10:42:43 -08:00 committed by GitHub
parent faadbba63c
commit ead4989947
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 4 deletions

View file

@ -35,6 +35,7 @@ import { APIResponse } from './fetch';
import type { Serializable } from '../../types/structs';
import type { BrowserContext } from './browserContext';
import { HarRouter } from './harRouter';
import { kBrowserOrContextClosedError } from '../common/errors';
export type NetworkCookie = {
name: string,
@ -271,6 +272,10 @@ export class Request extends ChannelOwner<channels.RequestChannel> implements ap
_fallbackOverridesForContinue() {
return this._fallbackOverrides;
}
_targetClosedPromise(): Promise<void> {
return this.serviceWorker()?._closedPromise || this.frame()._page?._closedOrCrashedPromise || new Promise(() => {});
}
}
export class Route extends ChannelOwner<channels.RouteChannel> implements api.Route {
@ -294,7 +299,7 @@ export class Route extends ChannelOwner<channels.RouteChannel> implements api.Ro
// does not have a Page initialized just yet.
return Promise.race([
promise,
this.request().serviceWorker()?._closedPromise || this.request().frame()._page?._closedOrCrashedPromise || Promise.resolve(),
this.request()._targetClosedPromise(),
]);
}
@ -520,7 +525,12 @@ export class Response extends ChannelOwner<channels.ResponseChannel> implements
}
async finished(): Promise<null> {
return this._finishedPromise.then(() => null);
return Promise.race([
this._finishedPromise.then(() => null),
this.request()._targetClosedPromise().then(() => {
throw new Error(kBrowserOrContextClosedError);
}),
]);
}
async body(): Promise<Buffer> {

View file

@ -109,7 +109,6 @@ it('should wait until response completes', async ({ page, server }) => {
});
it('should reject response.finished if page closes', async ({ page, server }) => {
it.fixme();
await page.goto(server.EMPTY_PAGE);
server.setRoute('/get', (req, res) => {
// In Firefox, |fetch| will be hanging until it receives |Content-Type| header
@ -130,7 +129,6 @@ it('should reject response.finished if page closes', async ({ page, server }) =>
});
it('should reject response.finished if context closes', async ({ page, server }) => {
it.fixme();
await page.goto(server.EMPTY_PAGE);
server.setRoute('/get', (req, res) => {
// In Firefox, |fetch| will be hanging until it receives |Content-Type| header