From 9257b44c0d02b2d7c603c774f85b764209cc7743 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Mon, 19 Oct 2020 21:48:22 -0500 Subject: [PATCH] Improved error handling for the fetch api --- lib/bigcommerce/api/utils/errors.ts | 4 +++- .../api/utils/fetch-graphql-api.ts | 2 +- lib/bigcommerce/api/utils/fetch-store-api.ts | 23 +++++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/bigcommerce/api/utils/errors.ts b/lib/bigcommerce/api/utils/errors.ts index 1cdd72214..bd7a995d8 100644 --- a/lib/bigcommerce/api/utils/errors.ts +++ b/lib/bigcommerce/api/utils/errors.ts @@ -4,12 +4,14 @@ export class BigcommerceGraphQLError extends Error {} export class BigcommerceApiError extends Error { status: number res: Response + data: any - constructor(msg: string, res: Response) { + constructor(msg: string, res: Response, data?: any) { super(msg) this.name = 'BigcommerceApiError' this.status = res.status this.res = res + this.data = data } } diff --git a/lib/bigcommerce/api/utils/fetch-graphql-api.ts b/lib/bigcommerce/api/utils/fetch-graphql-api.ts index aaf6e75ea..1e79f7c2f 100644 --- a/lib/bigcommerce/api/utils/fetch-graphql-api.ts +++ b/lib/bigcommerce/api/utils/fetch-graphql-api.ts @@ -23,7 +23,7 @@ export default async function fetchGraphqlApi( const json = await res.json() if (json.errors) { console.error(json.errors) - throw new Error('Failed to fetch API') + throw new Error('Failed to fetch BigCommerce API') } return json.data } diff --git a/lib/bigcommerce/api/utils/fetch-store-api.ts b/lib/bigcommerce/api/utils/fetch-store-api.ts index 0f0daedfe..44ec93b41 100644 --- a/lib/bigcommerce/api/utils/fetch-store-api.ts +++ b/lib/bigcommerce/api/utils/fetch-store-api.ts @@ -24,13 +24,22 @@ export default async function fetchStoreApi( ) } + const contentType = res.headers.get('Content-Type') + const isJSON = contentType?.includes('application/json') + if (!res.ok) { - throw new BigcommerceApiError(await getErrorText(res), res) + const data = isJSON ? await res.json() : await getTextOrNull(res) + const headers = getRawHeaders(res) + const msg = `Big Commerce API error (${ + res.status + }) \nHeaders: ${JSON.stringify(headers, null, 2)}\n${ + typeof data === 'string' ? data : JSON.stringify(data, null, 2) + }` + + throw new BigcommerceApiError(msg, res, data) } - const contentType = res.headers.get('Content-Type') - - if (!contentType?.includes('application/json')) { + if (!isJSON) { throw new BigcommerceApiError( `Fetch to Bigcommerce API failed, expected JSON content but found: ${contentType}`, res @@ -41,12 +50,6 @@ export default async function fetchStoreApi( return res.status === 204 ? null : await res.json() } -async function getErrorText(res: Response) { - return `Big Commerce API error (${res.status}) \n${JSON.stringify( - getRawHeaders(res) - )}\n ${await getTextOrNull(res)}` -} - function getRawHeaders(res: Response) { const headers: { [key: string]: string } = {}