From e44c337d0f3b7a4090ce9602f954540a5180ca3b Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Wed, 30 Jun 2021 15:34:09 +0200 Subject: [PATCH] feat: Allow HttpErrors to store cause and errorCode --- src/identity/interaction/util/IdpInteractionError.ts | 5 +++-- src/util/errors/BadRequestHttpError.ts | 9 +++++++-- src/util/errors/ConflictHttpError.ts | 5 +++-- src/util/errors/ForbiddenHttpError.ts | 5 +++-- src/util/errors/HttpError.ts | 12 ++++++++++-- src/util/errors/InternalServerError.ts | 5 +++-- src/util/errors/MethodNotAllowedHttpError.ts | 5 +++-- src/util/errors/NotFoundHttpError.ts | 5 +++-- src/util/errors/NotImplementedHttpError.ts | 6 ++++-- src/util/errors/UnauthorizedHttpError.ts | 5 +++-- src/util/errors/UnsupportedMediaTypeHttpError.ts | 5 +++-- 11 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/identity/interaction/util/IdpInteractionError.ts b/src/identity/interaction/util/IdpInteractionError.ts index 0b85bf833..b87c364d5 100644 --- a/src/identity/interaction/util/IdpInteractionError.ts +++ b/src/identity/interaction/util/IdpInteractionError.ts @@ -1,3 +1,4 @@ +import type { HttpErrorOptions } from '../../../util/errors/HttpError'; import { HttpError } from '../../../util/errors/HttpError'; /** @@ -7,8 +8,8 @@ import { HttpError } from '../../../util/errors/HttpError'; export class IdpInteractionError extends HttpError { public readonly prefilled: Record; - public constructor(status: number, message: string, prefilled: Record) { - super(status, 'IdpInteractionError', message); + public constructor(status: number, message: string, prefilled: Record, options?: HttpErrorOptions) { + super(status, 'IdpInteractionError', message, options); this.prefilled = prefilled; } diff --git a/src/util/errors/BadRequestHttpError.ts b/src/util/errors/BadRequestHttpError.ts index 7bc5acd15..a2d93dfd7 100644 --- a/src/util/errors/BadRequestHttpError.ts +++ b/src/util/errors/BadRequestHttpError.ts @@ -1,3 +1,4 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** @@ -8,9 +9,13 @@ export class BadRequestHttpError extends HttpError { /** * Default message is 'The given input is not supported by the server configuration.'. * @param message - Optional, more specific, message. + * @param options - Optional error options. */ - public constructor(message?: string) { - super(400, 'BadRequestHttpError', message ?? 'The given input is not supported by the server configuration.'); + public constructor(message?: string, options?: HttpErrorOptions) { + super(400, + 'BadRequestHttpError', + message ?? 'The given input is not supported by the server configuration.', + options); } public static isInstance(error: any): error is BadRequestHttpError { diff --git a/src/util/errors/ConflictHttpError.ts b/src/util/errors/ConflictHttpError.ts index efb887b06..bd0916b62 100644 --- a/src/util/errors/ConflictHttpError.ts +++ b/src/util/errors/ConflictHttpError.ts @@ -1,10 +1,11 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when a request conflict with current state of the server. */ export class ConflictHttpError extends HttpError { - public constructor(message?: string) { - super(409, 'ConflictHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(409, 'ConflictHttpError', message, options); } public static isInstance(error: any): error is ConflictHttpError { diff --git a/src/util/errors/ForbiddenHttpError.ts b/src/util/errors/ForbiddenHttpError.ts index 8539490dc..2758cd15e 100644 --- a/src/util/errors/ForbiddenHttpError.ts +++ b/src/util/errors/ForbiddenHttpError.ts @@ -1,11 +1,12 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when an agent is not allowed to access data. */ export class ForbiddenHttpError extends HttpError { - public constructor(message?: string) { - super(403, 'ForbiddenHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(403, 'ForbiddenHttpError', message, options); } public static isInstance(error: any): error is ForbiddenHttpError { diff --git a/src/util/errors/HttpError.ts b/src/util/errors/HttpError.ts index b5b206aa0..431513cc6 100644 --- a/src/util/errors/HttpError.ts +++ b/src/util/errors/HttpError.ts @@ -1,5 +1,10 @@ import { isError } from './ErrorUtil'; +export interface HttpErrorOptions { + cause?: unknown; + errorCode?: string; +} + /** * A class for all errors that could be thrown by Solid. * All errors inheriting from this should fix the status code thereby hiding the HTTP internals from other components. @@ -7,17 +12,20 @@ import { isError } from './ErrorUtil'; export class HttpError extends Error { protected static readonly statusCode: number; public readonly statusCode: number; + public readonly options: HttpErrorOptions; /** * Creates a new HTTP error. Subclasses should call this with their fixed status code. * @param statusCode - HTTP status code needed for the HTTP response. * @param name - Error name. Useful for logging and stack tracing. - * @param message - Message to be thrown. + * @param message - Error message. + * @param options - Optional options. */ - public constructor(statusCode: number, name: string, message?: string) { + public constructor(statusCode: number, name: string, message?: string, options: HttpErrorOptions = {}) { super(message); this.statusCode = statusCode; this.name = name; + this.options = options; } public static isInstance(error: any): error is HttpError { diff --git a/src/util/errors/InternalServerError.ts b/src/util/errors/InternalServerError.ts index 1619d5861..c1418c9ab 100644 --- a/src/util/errors/InternalServerError.ts +++ b/src/util/errors/InternalServerError.ts @@ -1,10 +1,11 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * A generic error message, given when an unexpected condition was encountered and no more specific message is suitable. */ export class InternalServerError extends HttpError { - public constructor(message?: string) { - super(500, 'InternalServerError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(500, 'InternalServerError', message, options); } public static isInstance(error: any): error is InternalServerError { diff --git a/src/util/errors/MethodNotAllowedHttpError.ts b/src/util/errors/MethodNotAllowedHttpError.ts index f2163374c..5df8cb692 100644 --- a/src/util/errors/MethodNotAllowedHttpError.ts +++ b/src/util/errors/MethodNotAllowedHttpError.ts @@ -1,10 +1,11 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when data was found for the requested identifier, but is not supported by the target resource. */ export class MethodNotAllowedHttpError extends HttpError { - public constructor(message?: string) { - super(405, 'MethodNotAllowedHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(405, 'MethodNotAllowedHttpError', message, options); } public static isInstance(error: any): error is MethodNotAllowedHttpError { diff --git a/src/util/errors/NotFoundHttpError.ts b/src/util/errors/NotFoundHttpError.ts index 7ce6d0624..df2dbb159 100644 --- a/src/util/errors/NotFoundHttpError.ts +++ b/src/util/errors/NotFoundHttpError.ts @@ -1,10 +1,11 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when no data was found for the requested identifier. */ export class NotFoundHttpError extends HttpError { - public constructor(message?: string) { - super(404, 'NotFoundHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(404, 'NotFoundHttpError', message, options); } public static isInstance(error: any): error is NotFoundHttpError { diff --git a/src/util/errors/NotImplementedHttpError.ts b/src/util/errors/NotImplementedHttpError.ts index 16df618a5..059e6dab0 100644 --- a/src/util/errors/NotImplementedHttpError.ts +++ b/src/util/errors/NotImplementedHttpError.ts @@ -1,11 +1,13 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; + /** * The server either does not recognize the request method, or it lacks the ability to fulfil the request. * Usually this implies future availability (e.g., a new feature of a web-service API). */ export class NotImplementedHttpError extends HttpError { - public constructor(message?: string) { - super(501, 'NotImplementedHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(501, 'NotImplementedHttpError', message, options); } public static isInstance(error: any): error is NotImplementedHttpError { diff --git a/src/util/errors/UnauthorizedHttpError.ts b/src/util/errors/UnauthorizedHttpError.ts index f68c69f44..3a3302c71 100644 --- a/src/util/errors/UnauthorizedHttpError.ts +++ b/src/util/errors/UnauthorizedHttpError.ts @@ -1,11 +1,12 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when an agent is not authorized. */ export class UnauthorizedHttpError extends HttpError { - public constructor(message?: string) { - super(401, 'UnauthorizedHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(401, 'UnauthorizedHttpError', message, options); } public static isInstance(error: any): error is UnauthorizedHttpError { diff --git a/src/util/errors/UnsupportedMediaTypeHttpError.ts b/src/util/errors/UnsupportedMediaTypeHttpError.ts index 0ca1542db..7f86fe51e 100644 --- a/src/util/errors/UnsupportedMediaTypeHttpError.ts +++ b/src/util/errors/UnsupportedMediaTypeHttpError.ts @@ -1,11 +1,12 @@ +import type { HttpErrorOptions } from './HttpError'; import { HttpError } from './HttpError'; /** * An error thrown when the media type of incoming data is not supported by a parser. */ export class UnsupportedMediaTypeHttpError extends HttpError { - public constructor(message?: string) { - super(415, 'UnsupportedMediaTypeHttpError', message); + public constructor(message?: string, options?: HttpErrorOptions) { + super(415, 'UnsupportedMediaTypeHttpError', message, options); } public static isInstance(error: any): error is UnsupportedMediaTypeHttpError {