chore: throw instead of returning error from fetch (#10451)

This commit is contained in:
Yury Semikhatsky 2021-11-19 20:32:29 -08:00 committed by GitHub
parent fde2f6a77f
commit 9c23a78c32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 84 deletions

View File

@ -184,9 +184,7 @@ export class APIRequestContext extends ChannelOwner<channels.APIRequestContextCh
failOnStatusCode: options.failOnStatusCode, failOnStatusCode: options.failOnStatusCode,
ignoreHTTPSErrors: options.ignoreHTTPSErrors, ignoreHTTPSErrors: options.ignoreHTTPSErrors,
}); });
if (result.error) return new APIResponse(this, result.response);
throw new Error(result.error);
return new APIResponse(this, result.response!);
}); });
} }

View File

@ -179,18 +179,16 @@ export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, c
} }
async fetch(params: channels.APIRequestContextFetchParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResult> { async fetch(params: channels.APIRequestContextFetchParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResult> {
const { fetchResponse, error } = await this._object.fetch(params); const fetchResponse = await this._object.fetch(params);
let response; return {
if (fetchResponse) { response: {
response = {
url: fetchResponse.url, url: fetchResponse.url,
status: fetchResponse.status, status: fetchResponse.status,
statusText: fetchResponse.statusText, statusText: fetchResponse.statusText,
headers: fetchResponse.headers, headers: fetchResponse.headers,
fetchUid: fetchResponse.fetchUid fetchUid: fetchResponse.fetchUid
}; }
} };
return { response, error };
} }
async fetchResponseBody(params: channels.APIRequestContextFetchResponseBodyParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResponseBodyResult> { async fetchResponseBody(params: channels.APIRequestContextFetchResponseBodyParams, metadata?: channels.Metadata): Promise<channels.APIRequestContextFetchResponseBodyResult> {

View File

@ -296,8 +296,7 @@ export type APIRequestContextFetchOptions = {
ignoreHTTPSErrors?: boolean, ignoreHTTPSErrors?: boolean,
}; };
export type APIRequestContextFetchResult = { export type APIRequestContextFetchResult = {
response?: APIResponse, response: APIResponse,
error?: string,
}; };
export type APIRequestContextFetchResponseBodyParams = { export type APIRequestContextFetchResponseBodyParams = {
fetchUid: string, fetchUid: string,

View File

@ -254,8 +254,7 @@ APIRequestContext:
failOnStatusCode: boolean? failOnStatusCode: boolean?
ignoreHTTPSErrors: boolean? ignoreHTTPSErrors: boolean?
returns: returns:
response: APIResponse? response: APIResponse
error: string?
fetchResponseBody: fetchResponseBody:
parameters: parameters:

View File

@ -85,78 +85,74 @@ export abstract class APIRequestContext extends SdkObject {
return uid; return uid;
} }
async fetch(params: channels.APIRequestContextFetchParams): Promise<{fetchResponse?: Omit<types.APIResponse, 'body'> & { fetchUid: string }, error?: string}> { async fetch(params: channels.APIRequestContextFetchParams): Promise<Omit<types.APIResponse, 'body'> & { fetchUid: string }> {
try { const headers: { [name: string]: string } = {};
const headers: { [name: string]: string } = {}; const defaults = this._defaultOptions();
const defaults = this._defaultOptions(); headers['user-agent'] = defaults.userAgent;
headers['user-agent'] = defaults.userAgent; headers['accept'] = '*/*';
headers['accept'] = '*/*'; headers['accept-encoding'] = 'gzip,deflate,br';
headers['accept-encoding'] = 'gzip,deflate,br';
if (defaults.extraHTTPHeaders) { if (defaults.extraHTTPHeaders) {
for (const { name, value } of defaults.extraHTTPHeaders) for (const { name, value } of defaults.extraHTTPHeaders)
headers[name.toLowerCase()] = value; headers[name.toLowerCase()] = value;
}
if (params.headers) {
for (const { name, value } of params.headers)
headers[name.toLowerCase()] = value;
}
const method = params.method?.toUpperCase() || 'GET';
const proxy = defaults.proxy;
let agent;
if (proxy) {
// TODO: support bypass proxy
const proxyOpts = url.parse(proxy.server);
if (proxyOpts.protocol?.startsWith('socks')) {
agent = new SocksProxyAgent({
host: proxyOpts.hostname,
port: proxyOpts.port || undefined,
});
} else {
if (proxy.username)
proxyOpts.auth = `${proxy.username}:${proxy.password || ''}`;
agent = new HttpsProxyAgent(proxyOpts);
}
}
const timeout = defaults.timeoutSettings.timeout(params);
const deadline = timeout && (monotonicTime() + timeout);
const options: https.RequestOptions & { maxRedirects: number, deadline: number } = {
method,
headers,
agent,
maxRedirects: 20,
timeout,
deadline
};
// rejectUnauthorized = undefined is treated as true in node 12.
if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)
options.rejectUnauthorized = false;
const requestUrl = new URL(params.url, defaults.baseURL);
if (params.params) {
for (const { name, value } of params.params)
requestUrl.searchParams.set(name, value);
}
let postData;
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method))
postData = serializePostData(params, headers);
else if (params.postData || params.jsonData || params.formData || params.multipartData)
throw new Error(`Method ${method} does not accept post data`);
if (postData)
headers['content-length'] = String(postData.byteLength);
const fetchResponse = await this._sendRequest(requestUrl, options, postData);
const fetchUid = this._storeResponseBody(fetchResponse.body);
if (params.failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400))
return { error: `${fetchResponse.status} ${fetchResponse.statusText}` };
return { fetchResponse: { ...fetchResponse, fetchUid } };
} catch (e) {
return { error: e instanceof Error ? e.message : String(e) };
} }
if (params.headers) {
for (const { name, value } of params.headers)
headers[name.toLowerCase()] = value;
}
const method = params.method?.toUpperCase() || 'GET';
const proxy = defaults.proxy;
let agent;
if (proxy) {
// TODO: support bypass proxy
const proxyOpts = url.parse(proxy.server);
if (proxyOpts.protocol?.startsWith('socks')) {
agent = new SocksProxyAgent({
host: proxyOpts.hostname,
port: proxyOpts.port || undefined,
});
} else {
if (proxy.username)
proxyOpts.auth = `${proxy.username}:${proxy.password || ''}`;
agent = new HttpsProxyAgent(proxyOpts);
}
}
const timeout = defaults.timeoutSettings.timeout(params);
const deadline = timeout && (monotonicTime() + timeout);
const options: https.RequestOptions & { maxRedirects: number, deadline: number } = {
method,
headers,
agent,
maxRedirects: 20,
timeout,
deadline
};
// rejectUnauthorized = undefined is treated as true in node 12.
if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)
options.rejectUnauthorized = false;
const requestUrl = new URL(params.url, defaults.baseURL);
if (params.params) {
for (const { name, value } of params.params)
requestUrl.searchParams.set(name, value);
}
let postData;
if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method))
postData = serializePostData(params, headers);
else if (params.postData || params.jsonData || params.formData || params.multipartData)
throw new Error(`Method ${method} does not accept post data`);
if (postData)
headers['content-length'] = String(postData.byteLength);
const fetchResponse = await this._sendRequest(requestUrl, options, postData);
const fetchUid = this._storeResponseBody(fetchResponse.body);
if (params.failOnStatusCode && (fetchResponse.status < 200 || fetchResponse.status >= 400))
throw new Error(`${fetchResponse.status} ${fetchResponse.statusText}`);
return { ...fetchResponse, fetchUid };
} }
private async _updateCookiesFromHeader(responseUrl: string, setCookie: string[]) { private async _updateCookiesFromHeader(responseUrl: string, setCookie: string[]) {