in src/https.ts [78:147]
export async function fetchJson<ResultType extends Json>(
uri: string,
requestOptions?: FetchRequestOptions,
data?: Buffer
): Promise<ResultType> {
let responseTimeout: NodeJS.Timeout;
return new Promise<ResultType>((resolve, reject) => {
const req = request(
uri,
{
method: "GET",
...requestOptions,
},
(response) => {
// Capture response data
// @types/node is incomplete so cast to any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(pipeline as any)(
[
response,
getJsonDestination(uri, response.statusCode, response.headers),
],
done
);
}
);
if (requestOptions?.responseTimeout) {
responseTimeout = setTimeout(
() =>
done(
new FetchError(
uri,
`Response time-out (after ${requestOptions.responseTimeout} ms.)`
)
),
requestOptions.responseTimeout
);
responseTimeout.unref(); // Don't block Node from exiting
}
function done(...args: [Error] | [null, ResultType]) {
if (responseTimeout) clearTimeout(responseTimeout);
if (args[0] == null) {
resolve(args[1]);
return;
}
// In case of errors, let the Agent (if any) know to abandon the socket
// This is probably best, because the socket may have become stale
/* istanbul ignore next */
req.socket?.emit("agentRemove");
// Turn error into FetchError so the URI is nicely captured in the message
let error = args[0];
if (!(error instanceof FetchError)) {
error = new FetchError(uri, error.message);
}
req.destroy();
reject(error);
}
// Handle errors while sending request
req.on("error", done);
// Signal end of request (include optional data)
req.end(data);
});
}