From ff106bb764613d6256ed81d9057b55cc48881914 Mon Sep 17 00:00:00 2001 From: catloversg <152669316+catloversg@users.noreply.github.com> Date: Thu, 24 Jul 2025 04:30:25 +0700 Subject: [PATCH] BUGFIX: Error message shows blob URL instead of script name (#2265) --- src/ErrorHandling/DisplayError.ts | 20 ++++++++++---------- src/Netscript/ErrorMessages.ts | 18 ++++++++++-------- src/Netscript/NetscriptHelpers.tsx | 3 +-- src/utils/ErrorHandler.ts | 21 ++++++--------------- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/ErrorHandling/DisplayError.ts b/src/ErrorHandling/DisplayError.ts index 4c19a0b59..ec796971c 100644 --- a/src/ErrorHandling/DisplayError.ts +++ b/src/ErrorHandling/DisplayError.ts @@ -1,21 +1,21 @@ import { Router } from "../ui/GameRoot"; import { SimplePage } from "@enums"; import { errorModalsAreSuppressed, ErrorRecord, ErrorState } from "./ErrorState"; +import type { WorkerScript } from "../Netscript/WorkerScript"; +import { parseBlobUrlInMessage } from "../Netscript/ErrorMessages"; let currentId = 0; -export const DisplayError = ( - message: string, - errorType: string, - scriptName = "", - hostname: string = "", - pid: number = -1, -) => { +export const DisplayError = (message: string, errorType: string, ws: WorkerScript | null = null) => { + const scriptName = ws?.scriptRef?.filename ?? ""; + const hostname = ws?.hostname ?? ""; + const pid = ws?.pid ?? -1; + const parsedMessage = ws ? parseBlobUrlInMessage(ws, message) : message; const errorPageOpen = Router.page() === SimplePage.RecentErrors; if (!errorPageOpen) { ErrorState.UnreadErrors++; } - const prior = findExistingErrorCopy(message, hostname); + const prior = findExistingErrorCopy(parsedMessage, hostname); if (prior) { prior.occurrences++; prior.time = new Date(); @@ -23,7 +23,7 @@ export const DisplayError = ( prior.pid = pid; } prior.server = hostname; - prior.message = message; + prior.message = parsedMessage; updateActiveError(prior); } else { @@ -32,7 +32,7 @@ export const DisplayError = ( server: hostname, errorType, scriptName, - message, + message: parsedMessage, pid, occurrences: 1, time: new Date(), diff --git a/src/Netscript/ErrorMessages.ts b/src/Netscript/ErrorMessages.ts index fc5fe31ea..f558cd0d6 100644 --- a/src/Netscript/ErrorMessages.ts +++ b/src/Netscript/ErrorMessages.ts @@ -1,5 +1,4 @@ import type { WorkerScript } from "./WorkerScript"; -import { ScriptDeath } from "./ScriptDeath"; import type { NetscriptContext } from "./APIWrapper"; /** Log a message to a script's logs */ @@ -7,14 +6,17 @@ export function log(ctx: NetscriptContext, message: () => string) { ctx.workerScript.log(ctx.functionPath, message); } -/** Creates an error message string containing hostname, scriptname, and the error message msg */ -export function basicErrorMessage(ws: WorkerScript | ScriptDeath, msg: string, type = "RUNTIME"): string { - if (!(ws instanceof ScriptDeath)) { - for (const [scriptUrl, script] of ws.scriptRef.dependencies) { - msg = msg.replace(new RegExp(scriptUrl, "g"), script.filename); - } +/** Error messages may contain blob URLs (). This function replaces those URLs with the script names. */ +export function parseBlobUrlInMessage(ws: WorkerScript, msg: string): string { + for (const [scriptUrl, script] of ws.scriptRef.dependencies) { + msg = msg.replaceAll(scriptUrl, script.filename); } - return `${type} ERROR\n${ws.name}@${ws.hostname} (PID - ${ws.pid})\n\n${msg}`; + return msg; +} + +/** Creates an error message string containing hostname, scriptname, and the error message msg */ +export function basicErrorMessage(ws: WorkerScript, msg: string, type = "RUNTIME"): string { + return `${type} ERROR\n${ws.name}@${ws.hostname} (PID - ${ws.pid})\n\n${parseBlobUrlInMessage(ws, msg)}`; } /** diff --git a/src/Netscript/NetscriptHelpers.tsx b/src/Netscript/NetscriptHelpers.tsx index 2126d41e0..698efd388 100644 --- a/src/Netscript/NetscriptHelpers.tsx +++ b/src/Netscript/NetscriptHelpers.tsx @@ -55,7 +55,7 @@ import { resolveFilePath, FilePath } from "../Paths/FilePath"; import { hasScriptExtension, ScriptFilePath } from "../Paths/ScriptFilePath"; import { CustomBoundary } from "../ui/Components/CustomBoundary"; import { ServerConstants } from "../Server/data/Constants"; -import { basicErrorMessage, errorMessage, log } from "./ErrorMessages"; +import { errorMessage, log } from "./ErrorMessages"; import { assertStringWithNSContext, debugType } from "./TypeAssertion"; import { canAccessBitNodeFeature, @@ -79,7 +79,6 @@ export const helpers = { hostReturnOptions, returnServerID, argsToString, - basicErrorMessage, errorMessage, validateHGWOptions, checkEnvFlags, diff --git a/src/utils/ErrorHandler.ts b/src/utils/ErrorHandler.ts index 079139f54..324400c82 100644 --- a/src/utils/ErrorHandler.ts +++ b/src/utils/ErrorHandler.ts @@ -1,7 +1,7 @@ import { ScriptDeath } from "../Netscript/ScriptDeath"; import type { WorkerScript } from "../Netscript/WorkerScript"; import { dialogBoxCreate } from "../ui/React/DialogBox"; -import { getErrorMessageWithStackAndCause, parseUnknownError } from "./ErrorHelper"; +import { getErrorMessageWithStackAndCause } from "./ErrorHelper"; import { DisplayError } from "../ErrorHandling/DisplayError"; @@ -11,7 +11,6 @@ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, i // No dialog for ScriptDeath return; } - const errorDetails = parseUnknownError(e); if (ws && typeof e === "string") { /** * - Attempt to strip out the error type, if present. @@ -28,19 +27,12 @@ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, i const errorType = e.match(/^(\w+) ERROR/)?.[1]; if (errorType) { const errorText = e.split(/\n/).slice(3).join("\n"); - DisplayError(initialText + errorText, errorType, ws.scriptRef.filename, ws.hostname, ws.pid); + DisplayError(initialText + errorText, errorType, ws); return; } - DisplayError(initialText + e, "RUNTIME", ws.scriptRef.filename, ws.hostname, ws.pid); + DisplayError(initialText + e, "RUNTIME", ws); } else if (e instanceof SyntaxError) { - const msg = `${e.message} (sorry we can't be more helpful)`; - DisplayError( - initialText + msg + (errorDetails.stack ?? ""), - "SYNTAX", - ws?.scriptRef?.filename, - ws?.hostname, - ws?.pid, - ); + DisplayError(initialText + getErrorMessageWithStackAndCause(e), "SYNTAX", ws); } else if (e instanceof Error) { // Ignore any cancellation errors from Monaco that get here if (e.name === "Canceled" && e.message === "Canceled") { @@ -56,13 +48,12 @@ export function handleUnknownError(e: unknown, ws: WorkerScript | null = null, i * tool of browsers will do that for us if we print the error to the console. */ console.error(e); - const msg = getErrorMessageWithStackAndCause(e); - DisplayError(initialText + msg, getErrorType(e.stack) ?? "RUNTIME", ws?.scriptRef?.filename, ws?.hostname, ws?.pid); + DisplayError(initialText + getErrorMessageWithStackAndCause(e), getErrorType(e.stack) ?? "RUNTIME", ws); } else if (typeof e !== "string") { console.error("Unexpected error:", e); const msg = `Unexpected type of error thrown. This error was likely thrown manually within a script. Error has been logged to the console.\n\nType of error: ${typeof e}\nValue of error: ${e}`; - DisplayError(msg, "UNKNOWN", ws?.scriptRef?.filename, ws?.hostname, ws?.pid); + DisplayError(msg, "UNKNOWN", ws); } }