Created
April 8, 2023 21:02
-
-
Save egargan-ft/0b54d27dd262740a8533d2d266db1116 to your computer and use it in GitHub Desktop.
Snippers for better error handling in Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Base error class that all application errors should extend. | |
* | |
* Like the native `Error`, but ensures subclasses are properly initialised and correctly typed. | |
*/ | |
export class BaseError extends Error { | |
constructor(message: string) { | |
super(message); | |
Object.defineProperty(this, "name", { value: new.target.name }); | |
Object.setPrototypeOf(this, new.target.prototype); | |
} | |
/** | |
* Adds a 'cause' for this error | |
*/ | |
from(cause: unknown): ExtError { | |
this.cause = cause; | |
return this; | |
} | |
} | |
type Constructor<T> = { new (...args: any[]): T }; | |
type ArrayType<T extends unknown[]> = T extends (infer U)[] ? U : never; | |
/** | |
* Returns true if the given error matches any of the given error types. | |
* | |
* @returns true if the given error is an instanceof one of the given error types, false otherwise | |
* | |
* @example | |
* ``` | |
* try { | |
* // ... | |
* } catch (err) { | |
* if (matchErr(err, MyApplicationError)) { | |
* console.log('Application failed in an expected way!'); | |
* } | |
* } | |
* ``` | |
*/ | |
export function matchErr<T extends Constructor<Error>[]>( | |
error: unknown, | |
...types: T | |
): error is InstanceType<ArrayType<T>> { | |
return types.some((type) => error instanceof type); | |
} | |
/** | |
* Returns true if the given `error` matches any of the given error `types`. | |
* | |
* @returns true if the given error's type matched one of the given error types | |
* @throws error if its type didnt match the given error types | |
* | |
* @example | |
* ``` | |
* try { | |
* // ... | |
* } catch (err) { | |
* if (matchErrOrThrow(err, MyApplicationError)) { | |
* console.log('Application failed in an expected way!'); | |
* } | |
* } | |
* ``` | |
*/ | |
export function matchErrOrThrow<T extends Constructor<Error>[]>( | |
error: unknown, | |
...types: T | |
): error is InstanceType<ArrayType<T>> { | |
if (matchErr(error, ...types)) { | |
return true; | |
} else { | |
throw error; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment