import { SpecifyError, specifyErrors } from '../../../errors/index.js'; import { getLastHttpResponseErrorMessage } from '../../index.js'; /** * @internal * @param fetchPromise */ export async function wrapFetchCall(fetchPromise: Promise) { try { const response = await fetchPromise; if (response.status < 200 || response.status >= 500) { throw new SpecifyError({ publicMessage: `Unexpected API response error with status code: ${response.status}.`, errorKey: specifyErrors.NETWORK_UNEXPECTED_ERROR.errorKey, httpStatusCode: response.status, }); } const parsedBody = await response.json(); if ( parsedBody !== null && typeof parsedBody === 'object' && !Array.isArray(parsedBody) && 'status' in parsedBody ) { if (parsedBody.status === 'success') { return parsedBody as T; } const lastMessage = getLastHttpResponseErrorMessage(parsedBody); throw new SpecifyError({ publicMessage: lastMessage.content, errorKey: lastMessage.errorKey, httpStatusCode: response.status, }); } throw new SpecifyError({ publicMessage: 'Invalid response body provided.', errorKey: specifyErrors.NETWORK_UNEXPECTED_ERROR.errorKey, }); } catch (error) { if (error instanceof SpecifyError) { throw error; } if ( error instanceof TypeError && error.cause && // @ts-expect-error - error cause is too fuzzy to be inferred 'code' in error.cause ) { switch (error.cause.code) { case 'ECONNREFUSED': throw new SpecifyError({ publicMessage: 'Specify HTTP API is not reachable.', errorKey: specifyErrors.NETWORK_UNEXPECTED_ERROR.errorKey, }); } } throw new SpecifyError({ publicMessage: 'Unexpected error while fetching Specify HTTP API.', errorKey: specifyErrors.NETWORK_UNEXPECTED_ERROR.errorKey, }); } }