Skip to content

Instantly share code, notes, and snippets.

@Fasteroid
Last active March 17, 2026 17:48
Show Gist options
  • Select an option

  • Save Fasteroid/52d63db3692e74e9ddaad6cad8603a14 to your computer and use it in GitHub Desktop.

Select an option

Save Fasteroid/52d63db3692e74e9ddaad6cad8603a14 to your computer and use it in GitHub Desktop.
Got sidetracked; made something silly.
/**
* Encapsulates multiple errors.\
* When thrown and not caught, throws all child errors (V8) (need to test in other JavaScript engines)
*
* Not to be confused with the native {@linkcode window.AggregateError | AggregateError}
*/
export class AggregateError2 extends Error {
/** List of all errors. */
public readonly errors: readonly Error[] = [];
/**
* Appends an error. Does nothing if we already threw this instance.
*/
public push(error: Error) {
if( this.threw ) return;
// @ts-ignore(2339); we just don't want external sources mutating this array
this.errors.push(error);
}
/**
* Prevents the child errors from throwing in console.\
* Due to implementation quirks of different JavaScript engines, you should probably call this if you intend to catch one of these.
*/
public defuse(){
this.threw = true;
}
private threw?: true;
private _stack: string;
public override get stack(): string {
if( !this.threw ) {
this.errors.forEach( (err) => setTimeout(() => { throw err }) ) // throw all the errors!
this.threw = true;
}
return this._stack;
}
constructor() {
super();
this._stack = (this as Error).stack ?? ''; // save the actual stack
delete (this as Error).stack; // force throw to go through our getter
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment