From bb36014f55de29e5bd196761bf2d7193aeec6509 Mon Sep 17 00:00:00 2001 From: peshomir <80340328+peshomir@users.noreply.github.com> Date: Mon, 14 Jul 2025 12:26:30 +0300 Subject: [PATCH] Error reporting improvements Arbitraty context can be added to reports of known errors by wrapping the problematic code in the debugWithContext function --- patches/patches.js | 2 +- src/debugging.js | 40 ++++++++++++++++++++++++++++++++++++++++ src/gameScriptUtils.js | 19 +------------------ src/main.js | 2 ++ 4 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 src/debugging.js diff --git a/patches/patches.js b/patches/patches.js index 6298749..1499f0a 100644 --- a/patches/patches.js +++ b/patches/patches.js @@ -7,7 +7,7 @@ export default (/** @type {ModUtils} */ modUtils) => { modUtils.insertCode( `window.removeEventListener("error", err); msg = e.lineno + " " + e.colno + "|" + getStack(e); /* here */`, - `__fx.utils.reportError(e, msg); + `__fx.reportError(e, msg); return alert("Error:\\n" + e.filename + " " + e.lineno + " " + e.colno + " " + e.message);` ) diff --git a/src/debugging.js b/src/debugging.js new file mode 100644 index 0000000..008af98 --- /dev/null +++ b/src/debugging.js @@ -0,0 +1,40 @@ +import { getVar } from "./gameInterface.js"; + +let debugContext = null; + +export function reportError(e, message) { + function tryGetVar(name) { + try { return getVar(name) } + catch (error) { return error.toString(); } + } + message = e.filename + " " + e.lineno + " " + e.colno + " " + e.message + "\n" + message; + fetch("https://fx.peshomir.workers.dev/stats/errors", { + body: JSON.stringify({ + message, + context: { + debug: debugContext, + gameState: tryGetVar("gameState"), + singleplayer: tryGetVar("gIsSingleplayer"), + swState: navigator.serviceWorker?.controller?.state, + location: window.location.toString(), + userAgent: navigator.userAgent, + dictionary: JSON.stringify(dictionary), + buildTimestamp, + scripts: Array.from(document.scripts).map(s => s.src) + } + }), + method: "POST" + }).catch(e => alert("Failed to report error: " + e)); +} + +export function debugWithContext(callback, context) { + try { + return callback(); + } catch (error) { + debugContext = context; + setTimeout(() => { + if (debugContext !== null) debugContext = null; + }); + throw error; + } +} \ No newline at end of file diff --git a/src/gameScriptUtils.js b/src/gameScriptUtils.js index 2179389..55ddbd1 100644 --- a/src/gameScriptUtils.js +++ b/src/gameScriptUtils.js @@ -22,22 +22,5 @@ function textStyleBasedOnDensity(playerID) { const playerBalances = getVar("playerBalances"), playerTerritories = getVar("playerTerritories"); return `hsl(${playerBalances[playerID] / (playerTerritories[playerID] * 1.5)}, 100%, 50%, 1)`; } -function reportError(e, message) { - message = e.filename + " " + e.lineno + " " + e.colno + " " + e.message + "\n" + message; - fetch("https://fx.peshomir.workers.dev/stats/errors", { - body: JSON.stringify({ - message, - context: { - swState: navigator.serviceWorker?.controller?.state, - location: window.location.toString(), - userAgent: navigator.userAgent, - dictionary, - buildTimestamp, - scripts: Array.from(document.scripts).map(s => s.src) - } - }), - method: "POST" - }).catch(e => alert("Failed to report error: " + e)); -} -export default { getMaxTroops, getDensity, isPointInRectangle, fillTextMultiline, textStyleBasedOnDensity, reportError } \ No newline at end of file +export default { getMaxTroops, getDensity, isPointInRectangle, fillTextMultiline, textStyleBasedOnDensity } \ No newline at end of file diff --git a/src/main.js b/src/main.js index cbb93b2..5ae24e3 100644 --- a/src/main.js +++ b/src/main.js @@ -23,6 +23,7 @@ import hoveringTooltip from "./hoveringTooltip.js"; import { keybindFunctions, keybindHandler, mobileKeybinds } from "./keybinds.js"; import customLobby from './customLobby.js'; import { displayChangelog } from './changelog.js'; +import { reportError } from './debugging.js'; const savedVersion = localStorage.getItem("fx_version"); if (savedVersion !== version) { @@ -42,6 +43,7 @@ __fx.keybindFunctions = keybindFunctions; __fx.keybindHandler = keybindHandler; __fx.mobileKeybinds = mobileKeybinds; __fx.donationsTracker = donationsTracker; +__fx.reportError = reportError; __fx.playerList = playerList; __fx.hoveringTooltip = hoveringTooltip; __fx.clanFilter = clanFilter;