UNPKG

ebay-api

Version:

eBay API for Node and Browser

190 lines (189 loc) 5.87 kB
// tslint:disable:max-classes-per-file import debug from 'debug'; const log = debug('ebay:error'); export const rawError = Symbol('raw-error'); /** * Error object for ease of capturing if some service depends on .toJSON() method to log something * * @ignore */ export class EBayError extends Error { constructor(message, description = '', meta = {}) { super(message); Object.setPrototypeOf(this, new.target.prototype); this.name = this.constructor.name; this.description = description; this.meta = meta; } /** * returns a JSON representation of the Error * * @return {Object} json representation of the Error */ toJSON() { return { message: this.message, description: this.description, stack: this.stack, type: this.constructor.name, meta: this.meta || null }; } } /** * thrown when Request.prototype.run() is called without having defined an eBay API call */ export class EbayNoCallError extends EBayError { constructor(msg = 'No eBay API call defined, please invoke one.') { super(msg); } } /** * thrown when attempting to load environment variables that don't exist */ export class ApiEnvError extends EBayError { constructor(key) { super(`Could not find ${key} in process.env.`); } } export const getErrorMessage = (err) => err.response?.data?.message || err.response?.data?.error?.[0]?.message || err.response?.data?.errors?.[0]?.message || err.errorMessage?.error?.message || err.Errors?.ShortMessage || err.message || 'eBay API request error'; export const getErrorDescription = (err) => err.response?.data?.error_description || err.response?.data?.error?.[0]?.longMessage || err.response?.data?.errors?.[0]?.longMessage || err.longMessage || err.Errors?.LongMessage || err.response?.statusText || ''; /** * Thrown when an Error occurs on eBay's side. */ export class EbayApiError extends EBayError { constructor(err) { const { message, description, meta } = mapEBayError(err); super(message, description, meta); } } export class EBayAccessDenied extends EbayApiError { } export class EBayInvalidGrant extends EbayApiError { } export class EBayNotFound extends EbayApiError { } EBayNotFound.code = 11001; export class EBayInvalidAccessToken extends EbayApiError { } export class EBayIAFTokenExpired extends EbayApiError { } EBayIAFTokenExpired.code = 21917053; export class EBayIAFTokenInvalid extends EbayApiError { } EBayIAFTokenInvalid.code = 21916984; export class EBayTokenRequired extends EbayApiError { } EBayTokenRequired.code = 930; export class EBayInvalidScope extends EbayApiError { } export const mapEBayError = (err) => { if (!err) { return {}; } let eBayError = {}; if (err.response?.data) { const data = err.response.data; if (Array.isArray(data.error)) { eBayError = data.error[0] ?? data; } else if (Array.isArray(data.errors)) { eBayError = data.errors[0] ?? data; } else if (typeof data.error === 'string') { eBayError = { message: data.error, description: data.error_description || '' }; } else if (typeof data === 'string') { eBayError = { message: data }; } else { eBayError = data; } } else if (err.Errors) { eBayError = err; } const error = { message: eBayError.message || getErrorMessage(err), description: eBayError.description || getErrorDescription(err), meta: { ...eBayError, [rawError]: err } }; if (err.response) { error.meta.res = { status: err.response.status, statusText: err.response.statusText, headers: err.response.headers, data: err.response.data ?? {} }; } if (err.request && err.config) { error.meta.req = { url: err.config.url, method: err.config.method, headers: err.config.headers, params: err.config.params }; } return error; }; export const handleEBayError = (err) => { log('handleEBayError', err); if (err instanceof EBayError) { throw err; } const { message, meta, description } = mapEBayError(err); if (meta.domain === 'ACCESS') { throw new EBayAccessDenied(err); } else if (meta.message === 'invalid_grant') { throw new EBayInvalidGrant(err); } else if (meta.errorId === EBayNotFound.code) { throw new EBayNotFound(err); } else if (meta.message === 'invalid_scope') { throw new EBayInvalidScope(err); } else if (meta.message === 'Invalid access token') { throw new EBayInvalidAccessToken(err); } throw new EBayError(message, description, meta); }; export const checkEBayResponse = (data) => { if (data.Ack === 'Failure') { if (data.Errors?.ErrorCode) { switch (data.Errors.ErrorCode) { case EBayIAFTokenExpired.code: throw new EBayIAFTokenExpired(data); case EBayIAFTokenInvalid.code: throw new EBayIAFTokenInvalid(data); case EBayTokenRequired.code: throw new EBayTokenRequired(data); } } throw new EbayApiError(data); } else if (data.errorMessage) { throw new EbayApiError(data); } };