From 5b6380a5c30e7d3473f3a13db3e2511dee26b207 Mon Sep 17 00:00:00 2001 From: catloversg <152669316+catloversg@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:22:13 +0700 Subject: [PATCH] MISC: Add more error info to error dialog and tail log (#1813) --- src/NetscriptWorker.ts | 11 ++++++++--- src/utils/ErrorHandler.ts | 3 ++- src/utils/ErrorHelper.ts | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/NetscriptWorker.ts b/src/NetscriptWorker.ts index 6e8b49a1b..7b60fdde6 100644 --- a/src/NetscriptWorker.ts +++ b/src/NetscriptWorker.ts @@ -37,6 +37,7 @@ import { CompleteRunOptions, getRunningScriptsByArgs } from "./Netscript/Netscri import { handleUnknownError } from "./utils/ErrorHandler"; import { isLegacyScript, legacyScriptExtension, resolveScriptFilePath, ScriptFilePath } from "./Paths/ScriptFilePath"; import { root } from "./Paths/Directory"; +import { getErrorMessageWithStackAndCause } from "./utils/ErrorHelper"; import { exceptionAlert } from "./utils/helpers/exceptionAlert"; export const NetscriptPorts = new Map(); @@ -349,10 +350,14 @@ Otherwise, this can also occur if you have attempted to launch a script from a t killWorkerScript(workerScript); workerScript.log("", () => "Script finished running"); }) - .catch(function (e) { - handleUnknownError(e, workerScript); + .catch(function (error) { + handleUnknownError(error, workerScript); killWorkerScript(workerScript); - workerScript.log("", () => (e instanceof ScriptDeath ? "Script killed." : "Script crashed due to an error.")); + workerScript.log("", () => + error instanceof ScriptDeath + ? "Script killed." + : getErrorMessageWithStackAndCause(error, "Script crashed due to an error: "), + ); }) .finally(() => { // The earnings are transferred to the parent if it still exists. diff --git a/src/utils/ErrorHandler.ts b/src/utils/ErrorHandler.ts index 86bcbe268..a89658c7c 100644 --- a/src/utils/ErrorHandler.ts +++ b/src/utils/ErrorHandler.ts @@ -2,6 +2,7 @@ import { basicErrorMessage } from "../Netscript/ErrorMessages"; import { ScriptDeath } from "../Netscript/ScriptDeath"; import type { WorkerScript } from "../Netscript/WorkerScript"; import { dialogBoxCreate } from "../ui/React/DialogBox"; +import { getErrorMessageWithStackAndCause } from "./ErrorHelper"; /** Generate an error dialog when workerscript is known */ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, initialText = "") { @@ -18,7 +19,7 @@ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, i } else if (e instanceof Error) { // Ignore any cancellation errors from Monaco that get here if (e.name === "Canceled" && e.message === "Canceled") return; - const msg = `${e.message}${e.stack ? `\nstack:\n${e.stack.toString()}` : ""}`; + const msg = getErrorMessageWithStackAndCause(e); e = ws ? basicErrorMessage(ws, msg) : `RUNTIME ERROR:\n\n${msg}`; } if (typeof e !== "string") { diff --git a/src/utils/ErrorHelper.ts b/src/utils/ErrorHelper.ts index 1d005c44a..a92ed6617 100644 --- a/src/utils/ErrorHelper.ts +++ b/src/utils/ErrorHelper.ts @@ -81,6 +81,21 @@ export function parseUnknownError(error: unknown): { }; } +export function getErrorMessageWithStackAndCause(error: unknown, prefix = ""): string { + const errorData = parseUnknownError(error); + let errorMessage = `${prefix}${errorData.errorAsString}`; + if (errorData.stack) { + errorMessage += `\nStack: ${errorData.stack}`; + } + if (errorData.causeAsString) { + errorMessage += `\nError cause: ${errorData.causeAsString}`; + if (errorData.causeStack) { + errorMessage += `\nCause stack: ${errorData.causeStack}`; + } + } + return errorMessage; +} + export function getErrorMetadata(error: unknown, errorInfo?: React.ErrorInfo, page?: Page): IErrorMetadata { const isElectron = navigator.userAgent.toLowerCase().includes(" electron/"); const env = process.env.NODE_ENV === "development" ? GameEnv.Development : GameEnv.Production;