in core.ts [514:596]
private async makeRequest<Req>(
optionsInput: PromiseOrValue<FinalRequestOptions<Req>>,
retriesRemaining: number | null,
): Promise<APIResponseProps> {
const options = await optionsInput;
const maxRetries = options.maxRetries ?? this.maxRetries;
if (retriesRemaining == null) {
retriesRemaining = maxRetries;
}
await this.prepareOptions(options);
const { req, url, timeout } = this.buildRequest(options, {
retryCount: maxRetries - retriesRemaining,
});
await this.prepareRequest(req, { url, options });
debug("request", url, options, req.headers);
if (options.signal?.aborted) {
throw new APIUserAbortError();
}
const controller = new AbortController();
const response = await this.fetchWithTimeout(url, req, timeout, controller)
.catch(castToError);
if (response instanceof Error) {
if (options.signal?.aborted) {
throw new APIUserAbortError();
}
if (retriesRemaining) {
return this.retryRequest(options, retriesRemaining);
}
if (response.name === "AbortError") {
throw new APIConnectionTimeoutError();
}
throw new APIConnectionError({ cause: response });
}
const responseHeaders = createResponseHeaders(response.headers);
if (!response.ok) {
if (retriesRemaining && this.shouldRetry(response)) {
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
debug(
`response (error; ${retryMessage})`,
response.status,
url,
responseHeaders,
);
return this.retryRequest(options, retriesRemaining, responseHeaders);
}
const errText = await response.text().catch((e) =>
castToError(e).message
);
const errJSON = safeJSON(errText);
const errMessage = errJSON ? undefined : errText;
const retryMessage = retriesRemaining
? `(error; no more retries left)`
: `(error; not retryable)`;
debug(
`response (error; ${retryMessage})`,
response.status,
url,
responseHeaders,
errMessage,
);
const err = this.makeStatusError(
response.status,
errJSON,
errMessage,
responseHeaders,
);
throw err;
}
return { response, options, controller };
}