diff --git a/browsers.json b/browsers.json index 16a071dc70..8ea8d8e60f 100644 --- a/browsers.json +++ b/browsers.json @@ -13,12 +13,12 @@ }, { "name": "firefox", - "revision": "1283", + "revision": "1284", "installByDefault": true }, { "name": "firefox-beta", - "revision": "1278", + "revision": "1279", "installByDefault": false }, { diff --git a/src/server/chromium/crNetworkManager.ts b/src/server/chromium/crNetworkManager.ts index edd3b8ecbd..6cbfb8c5c5 100644 --- a/src/server/chromium/crNetworkManager.ts +++ b/src/server/chromium/crNetworkManager.ts @@ -488,6 +488,12 @@ class RouteImpl implements network.RouteDelegate { const event = await this._responseInterceptedPromise; this._interceptionId = event.requestId; // FIXME: plumb status text from browser + if (event.responseErrorReason) { + this._client._sendMayFail('Fetch.continueRequest', { + requestId: event.requestId + }); + throw new Error(`Request failed: ${event.responseErrorReason}`); + } return new network.InterceptedResponse(request, event.responseStatusCode!, '', event.responseHeaders!); } diff --git a/src/server/firefox/protocol.d.ts b/src/server/firefox/protocol.d.ts index b3789fcca0..34a3667aab 100644 --- a/src/server/firefox/protocol.d.ts +++ b/src/server/firefox/protocol.d.ts @@ -935,6 +935,7 @@ export module Protocol { value: string; }[]; }; + error?: string; }; export type fulfillInterceptedRequestParameters = { requestId: string; diff --git a/src/server/webkit/wkInterceptableRequest.ts b/src/server/webkit/wkInterceptableRequest.ts index 2c50d175fb..c6f7e389fb 100644 --- a/src/server/webkit/wkInterceptableRequest.ts +++ b/src/server/webkit/wkInterceptableRequest.ts @@ -97,8 +97,8 @@ export class WKRouteImpl implements network.RouteDelegate { private readonly _requestId: string; _requestInterceptedCallback: () => void = () => {}; private readonly _requestInterceptedPromise: Promise; - _responseInterceptedCallback: ((responsePayload: Protocol.Network.Response) => void) | undefined; - private _responseInterceptedPromise: Promise | undefined; + _responseInterceptedCallback: ((payload: { response?: Protocol.Network.Response, error?: Protocol.Network.loadingFailedPayload }) => void) | undefined; + private _responseInterceptedPromise: Promise<{ response?: Protocol.Network.Response, error?: Protocol.Network.loadingFailedPayload }> | undefined; private readonly _page: WKPage; constructor(session: WKSession, page: WKPage, requestId: string) { @@ -165,8 +165,10 @@ export class WKRouteImpl implements network.RouteDelegate { }); if (!this._responseInterceptedPromise) return null; - const responsePayload = await this._responseInterceptedPromise; - return new InterceptedResponse(request, responsePayload.status, responsePayload.statusText, headersObjectToArray(responsePayload.headers)); + const { response, error } = await this._responseInterceptedPromise; + if (error) + throw new Error(`Request failed: ${error.errorText}`); + return new InterceptedResponse(request, response!.status, response!.statusText, headersObjectToArray(response!.headers)); } } diff --git a/src/server/webkit/wkPage.ts b/src/server/webkit/wkPage.ts index b682419b14..a13e0310a6 100644 --- a/src/server/webkit/wkPage.ts +++ b/src/server/webkit/wkPage.ts @@ -1008,7 +1008,7 @@ export class WKPage implements PageDelegate { session.sendMayFail('Network.interceptContinue', { requestId: event.requestId, stage: 'response' }); return; } - route._responseInterceptedCallback(event.response); + route._responseInterceptedCallback({ response: event.response }); } _onResponseReceived(event: Protocol.Network.responseReceivedPayload) { @@ -1068,6 +1068,9 @@ export class WKPage implements PageDelegate { // @see https://crbug.com/750469 if (!request) return; + const route = request._routeForRedirectChain(); + if (route?._responseInterceptedCallback) + route._responseInterceptedCallback({ error: event }); const response = request.request._existingResponse(); if (response) { response._serverAddrFinished(); diff --git a/tests/page/page-request-intercept.spec.ts b/tests/page/page-request-intercept.spec.ts index a4fcae2eea..729acd4dfd 100644 --- a/tests/page/page-request-intercept.spec.ts +++ b/tests/page/page-request-intercept.spec.ts @@ -85,6 +85,30 @@ it('should support fulfill after intercept', async ({page, server}) => { expect(await response.text()).toBe('Woof-Woof' + os.EOL); }); +it('should intercept failures', async ({page, browserName, server}) => { + server.setRoute('/title.html', (req, res) => { + req.destroy(); + }); + const requestPromise = server.waitForRequest('/title.html'); + let error; + await page.route('**', async route => { + try { + // @ts-expect-error + await route._intercept(); + await route.fulfill(); + } catch (e) { + error = e; + } + }); + const [request] = await Promise.all([ + requestPromise, + page.goto(server.PREFIX + '/title.html').catch(e => {}) + ]); + expect(error).toBeTruthy(); + expect(error.message).toContain('Request failed'); + expect(request.url).toBe('/title.html'); +}); + it('should support request overrides', async ({page, server, browserName, browserMajorVersion}) => { it.skip(browserName === 'chromium' && browserMajorVersion <= 91); const requestPromise = server.waitForRequest('/empty.html');