From 03c9ecca400a02684cd60229550dbad1190a5b6e Mon Sep 17 00:00:00 2001 From: Jan Scheffler Date: Fri, 29 Oct 2021 15:44:40 +0200 Subject: [PATCH] feat: improve error message for response.buffer() (#7669) --- src/common/HTTPResponse.ts | 28 +++++++++++++++++++++------- test/network.spec.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/common/HTTPResponse.ts b/src/common/HTTPResponse.ts index 3df6c62761a..9620c0cafee 100644 --- a/src/common/HTTPResponse.ts +++ b/src/common/HTTPResponse.ts @@ -18,6 +18,7 @@ import { Frame } from './FrameManager.js'; import { HTTPRequest } from './HTTPRequest.js'; import { SecurityDetails } from './SecurityDetails.js'; import { Protocol } from 'devtools-protocol'; +import { ProtocolError } from './Errors.js'; /** * @public @@ -147,13 +148,26 @@ export class HTTPResponse { if (!this._contentPromise) { this._contentPromise = this._bodyLoadedPromise.then(async (error) => { if (error) throw error; - const response = await this._client.send('Network.getResponseBody', { - requestId: this._request._requestId, - }); - return Buffer.from( - response.body, - response.base64Encoded ? 'base64' : 'utf8' - ); + try { + const response = await this._client.send('Network.getResponseBody', { + requestId: this._request._requestId, + }); + return Buffer.from( + response.body, + response.base64Encoded ? 'base64' : 'utf8' + ); + } catch (error) { + if ( + error instanceof ProtocolError && + error.originalMessage === 'No resource with given identifier found' + ) { + throw new ProtocolError( + 'Could not load body for this request. This might happen if the request is a preflight request.' + ); + } + + throw error; + } }); } return this._contentPromise; diff --git a/test/network.spec.ts b/test/network.spec.ts index de6f1402ba9..f5b875783a5 100644 --- a/test/network.spec.ts +++ b/test/network.spec.ts @@ -25,6 +25,7 @@ import { itFailsFirefox, describeFailsFirefox, } from './mocha-utils'; // eslint-disable-line import/extensions +import { HTTPResponse } from '../lib/cjs/puppeteer/api-docs-entry.js'; describe('network', function () { setupTestBrowserHooks(); @@ -366,6 +367,43 @@ describe('network', function () { const responseBuffer = await response.buffer(); expect(responseBuffer.equals(imageBuffer)).toBe(true); }); + it('should throw if the response does not have a body', async () => { + const { page, server } = getTestState(); + + await page.goto(server.PREFIX + '/empty.html'); + + server.setRoute('/test.html', (req, res) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Headers', 'x-ping'); + res.end('Hello World'); + }); + const url = server.CROSS_PROCESS_PREFIX + '/test.html'; + const responsePromise = new Promise((resolve) => { + page.on('response', (response) => { + // Get the preflight response. + if ( + response.request().method() === 'OPTIONS' && + response.url() === url + ) { + resolve(response); + } + }); + }); + + // Trigger a request with a preflight. + await page.evaluate<(src: string) => void>(async (src) => { + const response = await fetch(src, { + method: 'POST', + headers: { 'x-ping': 'pong' }, + }); + return response; + }, url); + + const response = await responsePromise; + await expect(response.buffer()).rejects.toThrowError( + 'Could not load body for this request. This might happen if the request is a preflight request.' + ); + }); }); describe('Response.statusText', function () {