fix(main): scope Olm error handler removal instead of clobbering globals
Surgically removes only the Olm-registered rethrow handler by inspecting listener source, rather than nuking all process error handlers. Adds a safety-net logger only when no other handlers remain. Addresses reviewer feedback: global process.removeAllListeners was removing handlers registered by other parts of the app/runtime.
This commit is contained in:
23
src/main.ts
23
src/main.ts
@@ -590,12 +590,27 @@ async function main() {
|
|||||||
await gateway.start();
|
await gateway.start();
|
||||||
|
|
||||||
// Olm WASM (matrix-js-sdk) registers process.on("uncaughtException", (e) => { throw e })
|
// Olm WASM (matrix-js-sdk) registers process.on("uncaughtException", (e) => { throw e })
|
||||||
// during Olm.init(). Without this fix, any uncaught async exception crashes the bot.
|
// during Olm.init(). That rethrow handler turns any uncaught async error into a crash.
|
||||||
// Must run AFTER gateway.start() since that's when the Matrix adapter initialises Olm.
|
// Surgically remove only the Olm-registered rethrow handlers, preserving any others.
|
||||||
process.removeAllListeners('uncaughtException');
|
for (const event of ['uncaughtException', 'unhandledRejection'] as const) {
|
||||||
process.removeAllListeners('unhandledRejection');
|
const listeners = process.listeners(event);
|
||||||
|
for (const listener of listeners) {
|
||||||
|
// Olm's handler is a one-liner that rethrows: (e) => { throw e }
|
||||||
|
// Detect by source — short function body that just throws its argument.
|
||||||
|
const src = listener.toString();
|
||||||
|
if (src.includes('throw') && src.length < 50) {
|
||||||
|
process.removeListener(event, listener as (...args: unknown[]) => void);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Safety net: log unhandled errors instead of crashing.
|
||||||
|
// Only adds if no other handlers remain (avoids clobbering app-registered handlers).
|
||||||
|
if (process.listenerCount('uncaughtException') === 0) {
|
||||||
process.on('uncaughtException', (err) => { log.error('Uncaught exception (suppressed):', err); });
|
process.on('uncaughtException', (err) => { log.error('Uncaught exception (suppressed):', err); });
|
||||||
|
}
|
||||||
|
if (process.listenerCount('unhandledRejection') === 0) {
|
||||||
process.on('unhandledRejection', (reason) => { log.error('Unhandled rejection (suppressed):', reason); });
|
process.on('unhandledRejection', (reason) => { log.error('Unhandled rejection (suppressed):', reason); });
|
||||||
|
}
|
||||||
|
|
||||||
// Start API server - uses gateway for delivery
|
// Start API server - uses gateway for delivery
|
||||||
const apiPort = parseInt(process.env.PORT || '8080', 10);
|
const apiPort = parseInt(process.env.PORT || '8080', 10);
|
||||||
|
|||||||
Reference in New Issue
Block a user