diff --git a/src/helpers/api-error-factory.ts b/src/helpers/api-error-factory.ts index 6b9410a7..d5def318 100644 --- a/src/helpers/api-error-factory.ts +++ b/src/helpers/api-error-factory.ts @@ -31,34 +31,37 @@ export function apiErrorFactory(error: AxiosError): ExtendableError { if (isAPIModelError(data)) { const modelError = data.errors.shift() if (modelError === undefined) { - return new SellingPartnerUnknownError( - { + return new SellingPartnerUnknownError({ + modelError: { code: code || 'UnknownError', message, }, headers, - ) + cause: error, + }) } + const errorParameters = { modelError, headers, cause: error } + switch (status) { case StatusCodes.BAD_REQUEST: - return new SellingPartnerBadRequestError(modelError, headers) + return new SellingPartnerBadRequestError(errorParameters) case StatusCodes.FORBIDDEN: - return new SellingPartnerForbiddenError(modelError, headers) + return new SellingPartnerForbiddenError(errorParameters) case StatusCodes.NOT_FOUND: - return new SellingPartnerNotFoundError(modelError, headers) + return new SellingPartnerNotFoundError(errorParameters) case StatusCodes.REQUEST_TOO_LONG: - return new SellingPartnerRequestTooLongError(modelError, headers) + return new SellingPartnerRequestTooLongError(errorParameters) case StatusCodes.UNSUPPORTED_MEDIA_TYPE: - return new SellingPartnerUnsupportedMediaTypeError(modelError, headers) + return new SellingPartnerUnsupportedMediaTypeError(errorParameters) case StatusCodes.TOO_MANY_REQUESTS: - return new SellingPartnerTooManyRequestsError(modelError, headers) + return new SellingPartnerTooManyRequestsError(errorParameters) case StatusCodes.INTERNAL_SERVER_ERROR: - return new SellingPartnerInternalServerError(modelError, headers) + return new SellingPartnerInternalServerError(errorParameters) case StatusCodes.SERVICE_UNAVAILABLE: - return new SellingPartnerServiceUnavailableError(modelError, headers) + return new SellingPartnerServiceUnavailableError(errorParameters) default: - return new SellingPartnerGenericError(modelError, headers) + return new SellingPartnerGenericError(errorParameters) } } } diff --git a/src/types/errors/selling-partner-api-errors.ts b/src/types/errors/selling-partner-api-errors.ts index 43423824..9787c7ab 100644 --- a/src/types/errors/selling-partner-api-errors.ts +++ b/src/types/errors/selling-partner-api-errors.ts @@ -27,6 +27,14 @@ export interface ModelError { details?: string } +export interface SellingPartnerErrorParameters { + modelError: ModelError + + headers: AxiosResponseHeaders + + cause: Error +} + export class SellingPartnerGenericError extends ExtendableError { public code: string @@ -36,13 +44,16 @@ export class SellingPartnerGenericError extends ExtendableError { public requestId: string - public constructor(error: ModelError, headers: AxiosResponseHeaders) { - super(error.details) + public cause: Error + + public constructor({ modelError, headers, cause }: SellingPartnerErrorParameters) { + super(modelError.details) - this.code = error.code - this.message = error.message - this.details = error.details + this.code = modelError.code + this.message = modelError.message + this.details = modelError.details this.requestId = headers['x-amzn-RequestId'] || headers['x-amzn-requestid'] || '' + this.cause = cause } } @@ -54,11 +65,11 @@ export class SellingPartnerUnsupportedMediaTypeError extends SellingPartnerGener export class SellingPartnerTooManyRequestsError extends SellingPartnerGenericError { public rateLimit?: number - public constructor(error: ModelError, headers: AxiosResponseHeaders) { - super(error, headers) + public constructor(parameters: SellingPartnerErrorParameters) { + super(parameters) this.rateLimit = - Number(headers['x-amzn-RateLimit-Limit']) || - Number(headers['x-amzn-ratelimit-limit']) || + Number(parameters.headers['x-amzn-RateLimit-Limit']) || + Number(parameters.headers['x-amzn-ratelimit-limit']) || undefined } } diff --git a/test/types/errors/errors.test.ts b/test/types/errors/errors.test.ts index 5795adc5..f616fac7 100644 --- a/test/types/errors/errors.test.ts +++ b/test/types/errors/errors.test.ts @@ -18,6 +18,8 @@ import { } from '../../../src' describe(`client`, () => { + const DEFAULT_INTERNAL_SERVER_ERROR_MESSAGE = 'Request failed with status code 500' + it(`should throw ${SellingPartnerForbiddenError.name} when pass invalid token`, async () => { expect.assertions(2) @@ -136,7 +138,7 @@ describe(`client`, () => { }) it(`should handle unknown error`, async () => { - expect.assertions(3) + expect.assertions(4) const { CA } = amazonMarketplaces assertMarketplaceHasSellingPartner(CA) @@ -161,11 +163,16 @@ describe(`client`, () => { await expect(client.getMarketplaceParticipations()).rejects.toHaveProperty( 'message', - 'Request failed with status code 500', + DEFAULT_INTERNAL_SERVER_ERROR_MESSAGE, ) await expect(client.getMarketplaceParticipations()).rejects.toHaveProperty( 'code', - 'ERR_BAD_RESPONSE', + AxiosError.ERR_BAD_RESPONSE, + ) + + await expect(client.getMarketplaceParticipations()).rejects.toHaveProperty( + 'cause', + new AxiosError(DEFAULT_INTERNAL_SERVER_ERROR_MESSAGE, AxiosError.ERR_BAD_RESPONSE), ) }) @@ -192,11 +199,11 @@ describe(`client`, () => { await expect(client.getMarketplaceParticipations()).rejects.toHaveProperty( 'message', - 'Request failed with status code 500', + DEFAULT_INTERNAL_SERVER_ERROR_MESSAGE, ) await expect(client.getMarketplaceParticipations()).rejects.toHaveProperty( 'code', - 'ERR_BAD_RESPONSE', + AxiosError.ERR_BAD_RESPONSE, ) }) })