diff --git a/api/src/errors/api-error.ts b/api/src/errors/api-error.ts index c88a77e524..75f91d420d 100644 --- a/api/src/errors/api-error.ts +++ b/api/src/errors/api-error.ts @@ -1,3 +1,5 @@ +import { BaseError } from './base-error'; + export enum ApiErrorType { BUILD_SQL = 'Error constructing SQL query', EXECUTE_SQL = 'Error executing SQL query', @@ -5,23 +7,9 @@ export enum ApiErrorType { UNKNOWN = 'Unknown Error' } -export class ApiError extends Error { - errors?: (string | object)[]; - +export class ApiError extends BaseError { constructor(name: ApiErrorType, message: string, errors?: (string | object)[], stack?: string) { - super(message); - - this.name = name; - this.errors = errors || []; - this.stack = stack; - - if (stack) { - this.stack = stack; - } - - if (!this.stack) { - Error.captureStackTrace(this); - } + super(name, message, errors, stack); } } diff --git a/api/src/errors/base-error.ts b/api/src/errors/base-error.ts new file mode 100644 index 0000000000..321029f691 --- /dev/null +++ b/api/src/errors/base-error.ts @@ -0,0 +1,25 @@ +export class BaseError extends Error { + errors: (string | object)[] = []; + + constructor(name: string, message: string, errors?: (string | object)[], stack?: string) { + super(message); + + this.name = name; + + for (const error of errors ?? []) { + if (error instanceof Error) { + // By default, properties of Error objects are not enumerable, so we need to manually extract them. + this.errors.push({ name: error.name, message: error.message }); + } else { + this.errors.push(error); + } + } + + // If a stack is provided, use it. Otherwise, generate a new stack trace. + if (stack) { + this.stack = stack; + } else { + Error.captureStackTrace(this); + } + } +} diff --git a/api/src/errors/http-error.ts b/api/src/errors/http-error.ts index 125f425578..c21d22965e 100644 --- a/api/src/errors/http-error.ts +++ b/api/src/errors/http-error.ts @@ -1,5 +1,6 @@ import { DatabaseError } from 'pg'; import { ApiError } from './api-error'; +import { BaseError } from './base-error'; export enum HTTPErrorType { BAD_REQUEST = 'Bad Request', @@ -9,24 +10,13 @@ export enum HTTPErrorType { INTERNAL_SERVER_ERROR = 'Internal Server Error' } -export class HTTPError extends Error { +export class HTTPError extends BaseError { status: number; - errors?: (string | object)[]; constructor(name: HTTPErrorType, status: number, message: string, errors?: (string | object)[], stack?: string) { - super(message); + super(name, message, errors, stack); - this.name = name; this.status = status; - this.errors = errors || []; - - if (stack) { - this.stack = stack; - } - - if (!this.stack) { - Error.captureStackTrace(this); - } } } @@ -125,9 +115,5 @@ export const ensureHTTPError = (error: HTTPError | ApiError | Error | any): HTTP ); } - if (error instanceof Error) { - return new HTTP500('Unexpected Error', [error.name, error.message]); - } - - return new HTTP500('Unexpected Error'); + return new HTTP500('Unexpected Error', [error]); };