From 731016472cd2611c2df3649cc770be20e75be080 Mon Sep 17 00:00:00 2001 From: sfwn Date: Wed, 25 Mar 2026 10:51:28 +0800 Subject: [PATCH] fix(discord): prevent uncaught gateway errors from crashing the process Move cleanup() after disconnect() in waitForDiscordGatewayStop so the error listener is still active during disconnect. Add a safety error listener in the lifecycle finally block to suppress late errors emitted by Carbon during teardown. Fixes the "Max reconnect attempts (0) reached after code 1006" uncaught exception that kills the entire gateway process when a Discord WebSocket drops and reconnection fails. --- extensions/discord/src/monitor.gateway.ts | 6 ++++-- extensions/discord/src/monitor/provider.lifecycle.ts | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/extensions/discord/src/monitor.gateway.ts b/extensions/discord/src/monitor.gateway.ts index d8e83a12a1e..8c89cf14567 100644 --- a/extensions/discord/src/monitor.gateway.ts +++ b/extensions/discord/src/monitor.gateway.ts @@ -33,10 +33,12 @@ export async function waitForDiscordGatewayStop( return; } settled = true; - cleanup(); try { gateway?.disconnect?.(); } finally { + // remove listeners after disconnect so late "error" events emitted + // during disconnect are still handled instead of becoming uncaught + cleanup(); resolve(); } }; @@ -45,10 +47,10 @@ export async function waitForDiscordGatewayStop( return; } settled = true; - cleanup(); try { gateway?.disconnect?.(); } finally { + cleanup(); reject(err); } }; diff --git a/extensions/discord/src/monitor/provider.lifecycle.ts b/extensions/discord/src/monitor/provider.lifecycle.ts index 884a0bded57..0ba9cd568e9 100644 --- a/extensions/discord/src/monitor/provider.lifecycle.ts +++ b/extensions/discord/src/monitor/provider.lifecycle.ts @@ -420,6 +420,13 @@ export async function runDiscordGatewayLifecycle(params: { } } finally { lifecycleStopping = true; + // attach a safety listener before releasing other listeners so that late + // "error" events emitted by Carbon during teardown do not become uncaught + // exceptions and crash the entire gateway process. + const suppressLateError = (err: unknown) => { + params.runtime.error?.(danger(`discord: suppressed late gateway error: ${String(err)}`)); + }; + gatewayEmitter?.on("error", suppressLateError); params.releaseEarlyGatewayErrorGuard?.(); unregisterGateway(params.accountId); stopGatewayLogging();