UNPKG

@shopify/shopify-api

Version:

Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks

151 lines (148 loc) 6.09 kB
import { HttpRequestError, GraphqlQueryError, HttpResponseError, HttpMaxRetriesError, HttpInternalError, HttpThrottlingError } from '../error.mjs'; import { LIBRARY_NAME, StatusCode } from '../types.mjs'; import { SHOPIFY_API_LIBRARY_VERSION } from '../version.mjs'; import { logger } from '../logger/index.mjs'; import { abstractRuntimeString } from '../../runtime/platform/runtime-string.mjs'; import { canonicalizeHeaders, getHeader } from '../../runtime/http/headers.mjs'; function getUserAgent(config) { let userAgentPrefix = `${LIBRARY_NAME} v${SHOPIFY_API_LIBRARY_VERSION} | ${abstractRuntimeString()}`; if (config.userAgentPrefix) { userAgentPrefix = `${config.userAgentPrefix} | ${userAgentPrefix}`; } return userAgentPrefix; } function serializeResponse(response) { if (!response) { return { error: 'No response object provided' }; } try { const { status, statusText, ok, redirected, type, url, headers } = response; const serialized = { status, statusText, ok, redirected, type, url, }; if (headers?.entries) { serialized.headers = Object.fromEntries(headers.entries()); } else if (headers) { serialized.headers = headers; } return serialized; } catch { return response; } } function clientLoggerFactory(config) { return (logContent) => { if (config.logger.httpRequests) { switch (logContent.type) { case 'HTTP-Response': { const responseLog = logContent.content; logger(config).debug('Received response for HTTP request', { requestParams: JSON.stringify(responseLog.requestParams), response: JSON.stringify(serializeResponse(responseLog.response)), }); break; } case 'HTTP-Retry': { const responseLog = logContent.content; logger(config).debug('Retrying HTTP request', { requestParams: JSON.stringify(responseLog.requestParams), retryAttempt: responseLog.retryAttempt, maxRetries: responseLog.maxRetries, response: responseLog.lastResponse ? JSON.stringify(serializeResponse(responseLog.lastResponse)) : 'undefined', }); break; } case 'HTTP-Response-GraphQL-Deprecation-Notice': { const responseLog = logContent.content; logger(config).debug('Received response containing Deprecated GraphQL Notice', { requestParams: JSON.stringify(responseLog.requestParams), deprecationNotice: responseLog.deprecationNotice, }); break; } default: { logger(config).debug(`HTTP request event: ${logContent.content}`); break; } } } }; } function throwFailedRequest(body, atMaxRetries, response) { if (typeof response === 'undefined') { const message = body?.errors?.message ?? ''; throw new HttpRequestError(`Http request error, no response available: ${message}`); } const responseHeaders = canonicalizeHeaders(Object.fromEntries(response.headers.entries() ?? [])); if (response.status === StatusCode.Ok && body.errors.graphQLErrors) { throw new GraphqlQueryError({ message: body.errors.graphQLErrors?.[0].message ?? 'GraphQL operation failed', response: response, headers: responseHeaders, body: body, }); } const errorMessages = []; if (body.errors) { errorMessages.push(JSON.stringify(body.errors, null, 2)); } const xRequestId = getHeader(responseHeaders, 'x-request-id'); if (xRequestId) { errorMessages.push(`If you report this error, please include this id: ${xRequestId}`); } const errorMessage = errorMessages.length ? `:\n${errorMessages.join('\n')}` : ''; const code = response.status; const statusText = response.statusText; switch (true) { case response.status === StatusCode.TooManyRequests: { if (atMaxRetries) { throw new HttpMaxRetriesError('Attempted the maximum number of retries for HTTP request.'); } else { const retryAfter = getHeader(responseHeaders, 'Retry-After'); throw new HttpThrottlingError({ message: `Shopify is throttling requests ${errorMessage}`, code, statusText, body, headers: responseHeaders, retryAfter: retryAfter ? parseFloat(retryAfter) : undefined, }); } } case response.status >= StatusCode.InternalServerError: if (atMaxRetries) { throw new HttpMaxRetriesError('Attempted the maximum number of retries for HTTP request.'); } else { throw new HttpInternalError({ message: `Shopify internal error${errorMessage}`, code, statusText, body, headers: responseHeaders, }); } default: throw new HttpResponseError({ message: `Received an error response (${response.status} ${response.statusText}) from Shopify${errorMessage}`, code, statusText, body, headers: responseHeaders, }); } } export { clientLoggerFactory, getUserAgent, throwFailedRequest }; //# sourceMappingURL=common.mjs.map