Skip to content

Undefined Token Error from ErrorMapper #174

Open
@mkaulfers

Description

@mkaulfers

I was continiously getting the error message

Undefined Token: ..... from the ErrorMapper. I partially fixed this, with the following code, however it's not ideal as it doesn't directly show the source as you'd expect, however yields better results than the Undefined Token

const safeConsole = {
  log: typeof console !== "undefined" && typeof console.log === "function" ? console.log : () => {},
  error: typeof console !== "undefined" && typeof console.error === "function" ? console.error : () => {}
};

export class ErrorMapper {
  private static _consumer?: SourceMapConsumer;

  public static get consumer(): SourceMapConsumer {
    if (!this._consumer) {
      try {
        const map = require("main.js.map");
        this._consumer = new SourceMapConsumer(map);
      } catch (e) {
        safeConsole.error("Failed to initialize SourceMapConsumer", e);
        throw e;
      }
    }

    return this._consumer;
  }

  public static cache: { [key: string]: string } = {};

  public static sourceMappedStackTrace(error: Error | string): string {
    const stack: string = error instanceof Error ? (error.stack as string) : error;
    if (this.cache.hasOwnProperty(stack)) {
      return this.cache[stack];
    }

    const re = /^\s+at\s+(.+?\s+)?\(?([0-z._\-\\\/]+):(\d+):(\d+)\)?$/gm;
    let match: RegExpExecArray | null;
    let outStack = error.toString();

    while ((match = re.exec(stack))) {
      if (match[2] === "main") {
        try {
          const pos = this.consumer.originalPositionFor({
            column: parseInt(match[4], 10),
            line: parseInt(match[3], 10)
          });

          if (pos.line != null) {
            if (pos.name) {
              outStack += `\n    at ${pos.name} (${pos.source}:${pos.line}:${pos.column})`;
            } else {
              outStack += `\n    at ${match[1] || ''}(${pos.source}:${pos.line}:${pos.column})`;
            }
          } else {
            break;
          }
        } catch (e) {
          safeConsole.error("Error while mapping stack trace", e);
          break;
        }
      } else {
        break;
      }
    }

    this.cache[stack] = outStack;
    return outStack;
  }

  public static wrapLoop(loop: () => void): () => void {
    return () => {
      try {
        loop();
      } catch (e) {
        if (e instanceof Error) {
          if ("sim" in Game.rooms) {
            safeConsole.log(`<span style='color:red'>Source maps don't work in the simulator - displaying original error<br>${_.escape(e.stack)}</span>`);
          } else {
            safeConsole.log(`<span style='color:red'>${_.escape(this.sourceMappedStackTrace(e))}</span>`);
          }
        } else {
          throw e;
        }
      }
    };
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions