UNPKG

@uppy/companion

Version:

OAuth helper and remote fetcher for Uppy's (https://uppy.io) extensible file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox and Google Drive, S3 and more :dog:

119 lines (106 loc) 3.16 kB
/** * ProviderApiError is error returned when an adapter encounters * an http error while communication with its corresponding provider */ export class ProviderApiError extends Error { /** * @param {string} message error message * @param {number} statusCode the http status code from the provider api */ constructor(message, statusCode) { super(`HTTP ${statusCode}: ${message}`) // Include statusCode to make it easier to debug this.name = 'ProviderApiError' this.statusCode = statusCode this.isAuthError = false } } export class ProviderUserError extends ProviderApiError { /** * @param {object} json arbitrary JSON.stringify-able object that will be passed to the client */ constructor(json) { super('User error', undefined) this.name = 'ProviderUserError' this.json = json } } /** * AuthError is error returned when an adapter encounters * an authorization error while communication with its corresponding provider * this signals to the client that the access token is invalid and needs to be * refreshed or the user needs to re-authenticate */ export class ProviderAuthError extends ProviderApiError { constructor() { super('invalid access token detected by Provider', 401) this.name = 'AuthError' this.isAuthError = true } } export function parseHttpError(err) { if (err?.name === 'HTTPError') { return { statusCode: err.response?.statusCode, body: err.response?.body, } } if (err?.name === 'HttpError') { return { statusCode: err.statusCode, body: err.responseJson, } } return undefined } /** * Convert an error instance to an http response if possible * * @param {Error | ProviderApiError} err the error instance to convert to an http json response * @returns {object | undefined} an object with a code and json field if the error can be converted to a response */ function errorToResponse(err) { // @ts-ignore if (err?.isAuthError) { return { code: 401, json: { message: err.message } } } if (err?.name === 'ValidationError') { return { code: 400, json: { message: err.message } } } if (err?.name === 'ProviderUserError') { // @ts-ignore return { code: 400, json: err.json } } if (err?.name === 'ProviderApiError') { // @ts-ignore if (err.statusCode >= 500) { // bad gateway i.e the provider APIs gateway return { code: 502, json: { message: err.message } } } // @ts-ignore if (err.statusCode === 429) { return { code: 429, message: err.message } } // @ts-ignore if (err.statusCode >= 400) { // 424 Failed Dependency return { code: 424, json: { message: err.message } } } } const httpError = parseHttpError(err) if (httpError) { // We proxy the response purely for ease of debugging return { code: 500, json: { statusCode: httpError.statusCode, body: httpError.body }, } } return undefined } export function respondWithError(err, res) { const errResp = errorToResponse(err) if (errResp) { res.status(errResp.code).json(errResp.json) return true } return false }