fix: preserve full error stacks in desktop renderer logs

Electron's console-message event only surfaces {level, message, line, sourceId}
without the stack, so uncaught errors showed up as 'line 1028 of chunk-*.js'
(SolidJS's rethrow site) with no way to find the real origin. Attach
window error and unhandledrejection listeners that log the full stack via
console.error, and reshape the main-process log line so newlines in the
stack survive instead of being JSON-escaped into one unreadable blob.
This commit is contained in:
LukeParkerDev
2026-04-17 11:28:51 +10:00
parent c510661ef3
commit 3e7e709884
2 changed files with 28 additions and 4 deletions

View File

@@ -258,16 +258,20 @@ async function initialize() {
function wireWindowDiagnostics(win: BrowserWindow, label: string) {
win.webContents.on("console-message", (_event, level, message, line, sourceId) => {
const payload = { level, message, line, sourceId }
// Render `message` as a block so multi-line stack traces survive; the
// previous shape stuffed the message into a JSON object which escaped
// `\n` and made stacks unreadable.
const location = sourceId ? ` [${sourceId}:${line}]` : ""
const text = `${label} renderer${location}\n${message}`
if (level >= 3) {
logger.error(`${label} renderer console`, payload)
logger.error(text)
return
}
if (level >= 2) {
logger.warn(`${label} renderer console`, payload)
logger.warn(text)
return
}
logger.log(`${label} renderer console`, payload)
logger.log(text)
})
win.webContents.on("did-fail-load", (_event, errorCode, errorDescription, validatedURL, isMainFrame) => {

View File

@@ -1,5 +1,25 @@
// @refresh reload
// Install global error listeners before any other module runs so that
// uncaught errors and rejected promises reach the main process with their
// full stacks intact. Electron's `console-message` event only forwards the
// rethrow site, so without these we lose the originating frame.
window.addEventListener("error", (event) => {
const err = event.error
const stack = err instanceof Error ? err.stack : null
console.error(
"[renderer uncaught]",
stack ?? event.message,
stack ? "" : `${event.filename}:${event.lineno}:${event.colno}`,
)
})
window.addEventListener("unhandledrejection", (event) => {
const reason = event.reason
const stack = reason instanceof Error ? reason.stack : null
console.error("[renderer unhandled rejection]", stack ?? reason)
})
import {
ACCEPTED_FILE_EXTENSIONS,
ACCEPTED_FILE_TYPES,