From 3f6f02240e4b72a0af3d53acd2317d5922a0ad11 Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 08:49:27 +0900 Subject: [PATCH 1/6] Add error-logging rejection handlers for discord client --- src/d2m/discord-client.js | 5 ++++- src/d2m/discord-packets.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/d2m/discord-client.js b/src/d2m/discord-client.js index 408c21c..f0d68d5 100644 --- a/src/d2m/discord-client.js +++ b/src/d2m/discord-client.js @@ -1,5 +1,6 @@ // @ts-check +const util = require("util") const DiscordTypes = require("discord-api-types/v10") const {Endpoints, SnowTransfer} = require("snowtransfer") const {reg} = require("../matrix/read-registration") @@ -55,7 +56,9 @@ class DiscordClient { this.guildChannelMap = new Map() if (listen !== "no") { this.cloud.on("event", message => { - discordPackets.onPacket(this, message, listen) + discordPackets.onPacket(this, message, listen).catch(e => { + console.error(`Unhandled error while processing Discord packet ${message.t}:\n${util.inspect(e, false, 4, false)}`) + }) }) } diff --git a/src/d2m/discord-packets.js b/src/d2m/discord-packets.js index 8317e0c..6a54aab 100644 --- a/src/d2m/discord-packets.js +++ b/src/d2m/discord-packets.js @@ -1,6 +1,7 @@ // @ts-check const assert = require("assert").strict +const util = require("util") const {scheduler} = require("timers/promises") const passthrough = require("../passthrough") const {sync} = passthrough @@ -216,7 +217,9 @@ async function onPacket(client, message, listen) { const optionalEvents = ["TYPING_START"] if (alwaysRealTimeEvents.includes(message.t) || homeserverStatus.homeserverStatus.isRealTime()) { // real time - dispatchPacketToBridge(client, message) + dispatchPacketToBridge(client, message).catch(e => { + console.error(`Unhandled error while sending Discord packet ${message.t} to the bridge:\n${util.inspect(e, false, 4, false)}`) + }) } else if (optionalEvents.includes(message.t)) { // when not real time, skip optional events } else { -- 2.34.1 From 023432cc11f64012c3eb37045145667f295f2f02 Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 08:49:31 +0900 Subject: [PATCH 2/6] start: add process-wide rejection handler with error logger Note that this also means that unhandled rejections now longer crashes the program, it just logs the error and continues as usual. --- start.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/start.js b/start.js index 84d4ef0..e745a33 100755 --- a/start.js +++ b/start.js @@ -8,6 +8,7 @@ process.title = "ooye" require("temporal-polyfill-lite/global") const fs = require("fs") +const util = require("util") const sqlite = require("better-sqlite3") const migrate = require("./src/db/migrate") const HeatSync = require("heatsync") @@ -16,6 +17,10 @@ const {reg} = require("./src/matrix/read-registration") const passthrough = require("./src/passthrough") const db = new sqlite("ooye.db") +process.on("unhandledRejection", e => { + console.error(`Unhandled promise rejection:\n${util.inspect(e, false, 4, false)}`) +}) + const sync = new HeatSync({ watchFunction(path, options, cb) { return fs.watchFile(path, options, (curr, prev) => { -- 2.34.1 From e505bfae821679aa7c8c072da1aa886aa8c95146 Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 08:49:34 +0900 Subject: [PATCH 3/6] Render error messages in a single log statement Getting 2 log events for every error made them a bit hard to both read and query for in a log ingester. --- src/d2m/discord-packets.js | 5 +++-- src/m2d/event-dispatcher.js | 4 +--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/d2m/discord-packets.js b/src/d2m/discord-packets.js index 6a54aab..a5e5a51 100644 --- a/src/d2m/discord-packets.js +++ b/src/d2m/discord-packets.js @@ -113,9 +113,10 @@ async function onPacket(client, message, listen) { await eventDispatcher.checkMissedLeaves(client, message.d) } catch (e) { if (firstReady) { - console.error("Failed to sync missed events. To retry, please fix this error and restart OOYE:") + console.error("Failed to sync missed events. To retry, please fix this error and restart OOYE:", e) + } else { + console.error(e) } - console.error(e) } } diff --git a/src/m2d/event-dispatcher.js b/src/m2d/event-dispatcher.js index c71f574..1e341e8 100644 --- a/src/m2d/event-dispatcher.js +++ b/src/m2d/event-dispatcher.js @@ -47,9 +47,7 @@ const {reg} = require("../matrix/read-registration") const errorReportStatus = sync.remember(() => ({lastReportedEvent: 0})) function printError(type, source, e, payload) { - console.error(`Error while processing a ${type} ${source} event:`) - console.error(e) - console.dir(payload, {depth: null}) + console.error(`Error while processing a ${type} ${source} event:\n${util.inspect(e, false, 4, false)}\n${util.inspect(payload, false, 4, false)}`) } /** @param {string} stack */ -- 2.34.1 From 8e9458d41ccfdd2a5e603d1170d49edcd214cd29 Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 20:51:20 +0900 Subject: [PATCH 4/6] Log failed `m2d` error reports Whenever `sendError` fails (the function responsible for sending reports about failed m2d bridging back to the matrix room), the error was silently dropped. We now log it as an error to the console. --- src/m2d/event-dispatcher.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/m2d/event-dispatcher.js b/src/m2d/event-dispatcher.js index 1e341e8..8ff1c46 100644 --- a/src/m2d/event-dispatcher.js +++ b/src/m2d/event-dispatcher.js @@ -128,7 +128,14 @@ async function sendError(roomID, source, type, e, payload) { || (e instanceof mreq.MatrixServerError && [502, 503].includes(e.httpStatus) && e.errcode === "CX_SERVER_ERROR") ) { // Matrix homeserver is down (reverse proxy indicated failure) + console.error([ + `Matrix homeserver is down, queueing ${type} ${source} event.`, + `Couldn't send error report to ${roomID}:`, + util.inspect(e, false, 4, false), + ].join("\n")) homeserverStatus.homeserverStatus.setErrorWithPacket([source, payload]) + } else { + console.error(`Couldn't send error report for a ${type} ${source} event to ${roomID}:\n${util.inspect(e, false, 4, false)}`) } } } -- 2.34.1 From d5972187ebff707b0bc436c1c86960c3eaaaeabd Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 21:31:27 +0900 Subject: [PATCH 5/6] Log `d2m` retrigger timeouts --- src/d2m/actions/retrigger.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d2m/actions/retrigger.js b/src/d2m/actions/retrigger.js index 7d7ce11..4c98abf 100644 --- a/src/d2m/actions/retrigger.js +++ b/src/d2m/actions/retrigger.js @@ -38,7 +38,10 @@ const storage = sync.remember(() => new class { this.resolves.set(id, (this.resolves.get(id) || []).concat(resolve)) // add to list in map value if (!this.timers.has(id)) { debugRetrigger(`[retrigger] SET TIMER id = ${id}`) - this.timers.set(id, setTimeout(() => this.resolve(id, false), 60 * 1000).unref()) // 1 minute + this.timers.set(id, setTimeout(() => { + console.warn(`[retrigger] gave up waiting for ${id} to finish bridging after 1 minute, skipping ${this.resolves.get(id)?.length ?? 0} pending changes`) + this.resolve(id, false) + }, 60 * 1000).unref()) // 1 minute } } -- 2.34.1 From 2a34e797c35b69db0fa8335b85c5f5ad20b7197d Mon Sep 17 00:00:00 2001 From: l1s5 Date: Sun, 25 Oct 2026 21:33:56 +0900 Subject: [PATCH 6/6] Make discord client log disconnections and errors outside `CONNECTION_DEBUG` These logs are useful in production environments, when investigating unexpected downtime and incidents. --- src/d2m/discord-client.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/d2m/discord-client.js b/src/d2m/discord-client.js index f0d68d5..88f366f 100644 --- a/src/d2m/discord-client.js +++ b/src/d2m/discord-client.js @@ -62,15 +62,15 @@ class DiscordClient { }) } + const addEventLogger = (eventName, logName) => { + this.cloud.on(eventName, (...args) => { + const d = new Date().toISOString().slice(0, 19) + console.error(`[${d} Client ${logName}]`, ...args) + }) + } + addEventLogger("error", "Error") + addEventLogger("disconnected", "Disconnected") if (CONNECTION_DEBUG) { - const addEventLogger = (eventName, logName) => { - this.cloud.on(eventName, (...args) => { - const d = new Date().toISOString().slice(0, 19) - console.error(`[${d} Client ${logName}]`, ...args) - }) - } - addEventLogger("error", "Error") - addEventLogger("disconnected", "Disconnected") addEventLogger("ready", "Ready") } } -- 2.34.1