2021-06-02 01:59:40 +00:00
|
|
|
/**
|
|
|
|
* An Error base-class that also provides some additional context.
|
|
|
|
*
|
|
|
|
* All first-party error handlers in Extollo can render the context as part of
|
|
|
|
* the display of the error (e.g. in the console, in the HTML response, &c.)
|
|
|
|
*
|
|
|
|
* @example
|
|
|
|
* ```typescript
|
|
|
|
* function myFunc(arg1, arg2) {
|
|
|
|
* // ...do something...
|
|
|
|
* throw new ErrorWithContext('Something went wrong!', { arg1, arg2 })
|
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*/
|
|
|
|
export class ErrorWithContext extends Error {
|
|
|
|
public context: {[key: string]: any} = {}
|
2021-06-03 03:36:25 +00:00
|
|
|
|
2021-06-02 01:59:40 +00:00
|
|
|
public originalError?: Error
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
message: string,
|
2021-06-03 03:36:25 +00:00
|
|
|
context?: {[key: string]: any},
|
2021-06-02 01:59:40 +00:00
|
|
|
) {
|
|
|
|
super(message)
|
2021-06-03 03:36:25 +00:00
|
|
|
if ( context ) {
|
|
|
|
this.context = context
|
|
|
|
}
|
2021-06-02 01:59:40 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-29 06:14:46 +00:00
|
|
|
|
|
|
|
export function withErrorContext<T>(closure: () => T, context: {[key: string]: any}): T {
|
|
|
|
try {
|
|
|
|
return closure()
|
|
|
|
} catch (e: unknown) {
|
|
|
|
if ( e instanceof ErrorWithContext ) {
|
|
|
|
e.context = {
|
|
|
|
...e.context,
|
|
|
|
...context,
|
|
|
|
}
|
|
|
|
throw e
|
|
|
|
} else if ( e instanceof Error ) {
|
|
|
|
const ewc = new ErrorWithContext(e.message, context)
|
|
|
|
ewc.stack = e.stack
|
|
|
|
ewc.name = e.name
|
|
|
|
ewc.originalError = e
|
|
|
|
throw ewc
|
|
|
|
} else {
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|