MCPcopy
hub / github.com/sindresorhus/ky / function_

Method function_

source/core/Ky.ts:153–253  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

151 const ky = new Ky(input, initHookOptions);
152
153 const function_ = async (): Promise<Response | void> => {
154 if (typeof ky.#options.timeout === 'number' && ky.#options.timeout > maxSafeTimeout) {
155 throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
156 }
157
158 if (typeof ky.#options.totalTimeout === 'number' && ky.#options.totalTimeout > maxSafeTimeout) {
159 throw new RangeError(`The \`totalTimeout\` option cannot be greater than ${maxSafeTimeout}`);
160 }
161
162 // Delay the fetch so that body method shortcuts can set the Accept header
163 await Promise.resolve();
164 const beforeRequestResponse = await ky.#runBeforeRequestHooks();
165 let response = beforeRequestResponse ?? await ky.#retry(async () => ky.#fetch());
166 let responseFromHook = beforeRequestResponse !== undefined
167 || ky.#consumeReturnedResponseFromBeforeRetryHook();
168
169 for (;;) {
170 // `undefined` means a hook stopped the flow without providing a response.
171 // Non-native Responses still continue through Ky if they pass `isResponseInstance()`.
172 if (response === undefined) {
173 return response;
174 }
175
176 if (isResponseInstance(response)) {
177 try {
178 // eslint-disable-next-line no-await-in-loop
179 response = await ky.#runAfterResponseHooks(response);
180 } catch (error) {
181 if (!(error instanceof ForceRetryError)) {
182 throw error;
183 }
184
185 // eslint-disable-next-line no-await-in-loop
186 const retriedResponse: Response | void = await ky.#retryFromError(error, async () => ky.#fetch());
187 if (retriedResponse === undefined) {
188 return retriedResponse;
189 }
190
191 response = retriedResponse;
192 responseFromHook = ky.#consumeReturnedResponseFromBeforeRetryHook();
193 continue;
194 }
195 }
196
197 const currentResponse: Response = response;
198
199 // Opaque responses (`response.type === 'opaque'`) from `no-cors` requests always have `status: 0` and `ok: false`, but this is not a failure - the actual status is hidden by the browser.
200 if (!currentResponse.ok && currentResponse.type !== 'opaque' && (
201 typeof ky.#options.throwHttpErrors === 'function'
202 ? ky.#options.throwHttpErrors(currentResponse.status)
203 : ky.#options.throwHttpErrors
204 )) {
205 // `request` must reflect the request that actually failed, but `options` stays as Ky's
206 // normalized options snapshot. Replacement `Request` instances do not preserve the
207 // original `BodyInit`, so trying to make `options` mirror arbitrary requests would be lossy.
208 const httpError: HTTPError = new HTTPError(currentResponse, ky.#getResponseRequest(currentResponse), ky.#getNormalizedOptions());
209 const errorToThrow: Error = httpError;
210 // eslint-disable-next-line no-await-in-loop

Callers

nothing calls this directly

Calls 13

isResponseInstanceFunction · 0.85
streamResponseFunction · 0.85
#retryMethod · 0.80
#fetchMethod · 0.80
#retryFromErrorMethod · 0.80
#getResponseRequestMethod · 0.80
#getNormalizedOptionsMethod · 0.80
#getResponseDataMethod · 0.80
#decorateResponseMethod · 0.80

Tested by

no test coverage detected