time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

IError.ts (3154B)


      1 import { LocationRange } from "peggy";
      2 import { Frame, FrameStack } from "../reducer/frameStack.js";
      3 import { ErrorMessage, REJavaScriptExn, REOther } from "./messages.js";
      4 
      5 // "I" stands for "Internal", since we also have a more public SqError proxy
      6 export class IRuntimeError extends Error {
      7   // TODO - it would be better to store `m` in `cause`, to like native Error objects do.
      8   private constructor(
      9     public m: ErrorMessage,
     10     public frameStack: FrameStack
     11   ) {
     12     // Should we pass `m.toString()`?
     13     // It'd be a bit costly and we override `IError.toString()` anyway.
     14     super();
     15   }
     16 
     17   // This shouldn't be used much, since frame stack will be empty.
     18   // But it's useful for global errors, e.g. in SqProject or somethere in the frontend.
     19   static fromMessage(message: ErrorMessage) {
     20     return new IRuntimeError(message, FrameStack.make());
     21   }
     22 
     23   static fromMessageWithFrameStack(
     24     message: ErrorMessage,
     25     frameStack: FrameStack
     26   ): IRuntimeError {
     27     return new IRuntimeError(message, frameStack);
     28   }
     29 
     30   // This shouldn't be used for most runtime errors - the resulting error would have an empty framestack.
     31   static fromException(exn: unknown) {
     32     if (exn instanceof IRuntimeError) {
     33       return exn;
     34     } else if (exn instanceof ErrorMessage) {
     35       return IRuntimeError.fromMessage(exn);
     36     } else if (exn instanceof Error) {
     37       return IRuntimeError.fromMessage(
     38         new REJavaScriptExn(exn.message, exn.name)
     39       );
     40     } else {
     41       return IRuntimeError.fromMessage(new REOther("Unknown exception"));
     42     }
     43   }
     44 
     45   override toString() {
     46     return this.m.toString();
     47   }
     48 
     49   toStringWithDetails() {
     50     return (
     51       this.toString() +
     52       (this.frameStack.isEmpty()
     53         ? ""
     54         : "\nStack trace:\n" + this.frameStack.toString())
     55     );
     56   }
     57 
     58   getTopFrame(): Frame | undefined {
     59     return this.frameStack.getTopFrame();
     60   }
     61 
     62   getFrameArray(): Frame[] {
     63     return this.frameStack.toFrameArray();
     64   }
     65 }
     66 
     67 // converts raw exceptions into exceptions with framestack attached
     68 // already converted exceptions won't be affected
     69 export function rethrowWithFrameStack(
     70   err: unknown,
     71   frameStack: FrameStack
     72 ): never {
     73   if (err instanceof IRuntimeError) {
     74     throw err; // exception already has a framestack
     75   } else if (err instanceof ErrorMessage) {
     76     throw IRuntimeError.fromMessageWithFrameStack(err, frameStack); // probably comes from FunctionRegistry, adding framestack
     77   } else if (err instanceof Error) {
     78     throw IRuntimeError.fromMessageWithFrameStack(
     79       new REJavaScriptExn(err.message, err.name),
     80       frameStack
     81     );
     82   } else {
     83     throw IRuntimeError.fromMessageWithFrameStack(
     84       new REOther("Unknown exception"),
     85       frameStack
     86     );
     87   }
     88 }
     89 
     90 export class ICompileError extends Error {
     91   constructor(
     92     public override message: string,
     93     public location: LocationRange
     94   ) {
     95     super();
     96   }
     97 
     98   override toString() {
     99     return this.message;
    100   }
    101 
    102   toStringWithDetails() {
    103     return (
    104       this.toString() +
    105       "\nLocation:\n  " +
    106       `at line ${this.location.start.line}, column ${this.location.start.column}, file ${this.location.source}`
    107     );
    108   }
    109 }