errors: added ForwardedError, unknown cause, and unknown fields in ErrorLike

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-10-07 23:54:24 +02:00
parent 6077d61e73
commit 9d18bc8ba4
6 changed files with 40 additions and 7 deletions
+17 -6
View File
@@ -14,17 +14,28 @@
* limitations under the License.
*/
import { isError } from './assertion';
/** @public */
export class CustomErrorBase extends Error {
readonly cause?: Error;
constructor(message?: string, cause?: Error) {
constructor(message?: string, cause?: Error | unknown) {
let assignedCause: Error | undefined = undefined;
let fullMessage = message;
if (cause) {
if (fullMessage) {
fullMessage += `; caused by ${cause}`;
if (cause !== undefined) {
let causeStr;
if (isError(cause)) {
assignedCause = cause;
causeStr = String(cause);
} else {
fullMessage = `caused by ${cause}`;
causeStr = `unknown error '${cause}'`;
}
if (fullMessage) {
fullMessage += `; caused by ${causeStr}`;
} else {
fullMessage = `caused by ${causeStr}`;
}
}
@@ -33,6 +44,6 @@ export class CustomErrorBase extends Error {
Error.captureStackTrace?.(this, this.constructor);
this.name = this.constructor.name;
this.cause = cause;
this.cause = assignedCause;
}
}
+1
View File
@@ -18,6 +18,7 @@ export type ErrorLike = {
name: string;
message: string;
stack?: string;
[unknownKeys: string]: unknown;
};
export function isError(val: unknown): val is ErrorLike {
+2 -1
View File
@@ -18,7 +18,8 @@ import * as errors from './common';
describe('common', () => {
it('extends Error properly', () => {
for (const [name, E] of Object.entries(errors)) {
const { ForwardedError: _, ...optionalCauseErrors } = { ...errors };
for (const [name, E] of Object.entries(optionalCauseErrors)) {
const error = new E('abcdef');
expect(error.name).toBe(name);
expect(error.message).toBe('abcdef');
+17
View File
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { isError } from './assertion';
import { CustomErrorBase } from './CustomErrorBase';
/*
@@ -72,3 +73,19 @@ export class ConflictError extends CustomErrorBase {}
* @public
*/
export class NotModifiedError extends CustomErrorBase {}
/**
* An error that forwards an underlying cause with additional context in the message.
*
* The `name` property of the error will be inherited from the `cause` if
* possible, and will otherwise be set to `'Error'`.
*
* @public
*/
export class ForwardedError extends CustomErrorBase {
constructor(message: string, cause: Error | unknown) {
super(message, cause);
this.name = isError(cause) ? this.constructor.name : 'Error';
}
}
+1
View File
@@ -19,6 +19,7 @@ export type { ErrorLike } from './assertion';
export {
AuthenticationError,
ConflictError,
ForwardedError,
InputError,
NotAllowedError,
NotFoundError,