mirror of
https://github.com/anthropics/claude-plugins-official.git
synced 2026-05-11 14:05:52 -03:00
discord: port resilience fixes from telegram
Same patterns as #812/#813 for the discord channel:
- process-level unhandledRejection/uncaughtException handlers
- client.on('error') to log discord.js errors
- mcp.notification().catch() so inbound delivery failures surface
- stdin close / SIGTERM -> client.destroy() + exit (zombie fix)
- .unref() the approval-check interval
- client.login().catch() to log+exit on bad token instead of crashing
Discord is inherently more resilient than telegram (discord.js
auto-reconnects, no 409 equivalent), but these gaps were still there.
This commit is contained in:
parent
90accf6fd2
commit
aa71c24314
@ -58,6 +58,15 @@ if (!TOKEN) {
|
|||||||
}
|
}
|
||||||
const INBOX_DIR = join(STATE_DIR, 'inbox')
|
const INBOX_DIR = join(STATE_DIR, 'inbox')
|
||||||
|
|
||||||
|
// Last-resort safety net — without these the process dies silently on any
|
||||||
|
// unhandled promise rejection. With them it logs and keeps serving tools.
|
||||||
|
process.on('unhandledRejection', err => {
|
||||||
|
process.stderr.write(`discord channel: unhandled rejection: ${err}\n`)
|
||||||
|
})
|
||||||
|
process.on('uncaughtException', err => {
|
||||||
|
process.stderr.write(`discord channel: uncaught exception: ${err}\n`)
|
||||||
|
})
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.DirectMessages,
|
GatewayIntentBits.DirectMessages,
|
||||||
@ -342,7 +351,7 @@ function checkApprovals(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!STATIC) setInterval(checkApprovals, 5000)
|
if (!STATIC) setInterval(checkApprovals, 5000).unref()
|
||||||
|
|
||||||
// Discord caps messages at 2000 chars (hard limit — larger sends reject).
|
// Discord caps messages at 2000 chars (hard limit — larger sends reject).
|
||||||
// Split long replies, preferring paragraph boundaries when chunkMode is
|
// Split long replies, preferring paragraph boundaries when chunkMode is
|
||||||
@ -637,6 +646,25 @@ mcp.setRequestHandler(CallToolRequestSchema, async req => {
|
|||||||
|
|
||||||
await mcp.connect(new StdioServerTransport())
|
await mcp.connect(new StdioServerTransport())
|
||||||
|
|
||||||
|
// When Claude Code closes the MCP connection, stdin gets EOF. Without this
|
||||||
|
// the gateway stays connected as a zombie holding resources.
|
||||||
|
let shuttingDown = false
|
||||||
|
function shutdown(): void {
|
||||||
|
if (shuttingDown) return
|
||||||
|
shuttingDown = true
|
||||||
|
process.stderr.write('discord channel: shutting down\n')
|
||||||
|
setTimeout(() => process.exit(0), 2000)
|
||||||
|
void Promise.resolve(client.destroy()).finally(() => process.exit(0))
|
||||||
|
}
|
||||||
|
process.stdin.on('end', shutdown)
|
||||||
|
process.stdin.on('close', shutdown)
|
||||||
|
process.on('SIGTERM', shutdown)
|
||||||
|
process.on('SIGINT', shutdown)
|
||||||
|
|
||||||
|
client.on('error', err => {
|
||||||
|
process.stderr.write(`discord channel: client error: ${err}\n`)
|
||||||
|
})
|
||||||
|
|
||||||
client.on('messageCreate', msg => {
|
client.on('messageCreate', msg => {
|
||||||
if (msg.author.bot) return
|
if (msg.author.bot) return
|
||||||
handleInbound(msg).catch(e => process.stderr.write(`discord: handleInbound failed: ${e}\n`))
|
handleInbound(msg).catch(e => process.stderr.write(`discord: handleInbound failed: ${e}\n`))
|
||||||
@ -685,7 +713,7 @@ async function handleInbound(msg: Message): Promise<void> {
|
|||||||
// forgeable by any allowlisted sender typing that string.
|
// forgeable by any allowlisted sender typing that string.
|
||||||
const content = msg.content || (atts.length > 0 ? '(attachment)' : '')
|
const content = msg.content || (atts.length > 0 ? '(attachment)' : '')
|
||||||
|
|
||||||
void mcp.notification({
|
mcp.notification({
|
||||||
method: 'notifications/claude/channel',
|
method: 'notifications/claude/channel',
|
||||||
params: {
|
params: {
|
||||||
content,
|
content,
|
||||||
@ -698,6 +726,8 @@ async function handleInbound(msg: Message): Promise<void> {
|
|||||||
...(atts.length > 0 ? { attachment_count: String(atts.length), attachments: atts.join('; ') } : {}),
|
...(atts.length > 0 ? { attachment_count: String(atts.length), attachments: atts.join('; ') } : {}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
}).catch(err => {
|
||||||
|
process.stderr.write(`discord channel: failed to deliver inbound to Claude: ${err}\n`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,4 +735,7 @@ client.once('ready', c => {
|
|||||||
process.stderr.write(`discord channel: gateway connected as ${c.user.tag}\n`)
|
process.stderr.write(`discord channel: gateway connected as ${c.user.tag}\n`)
|
||||||
})
|
})
|
||||||
|
|
||||||
await client.login(TOKEN)
|
client.login(TOKEN).catch(err => {
|
||||||
|
process.stderr.write(`discord channel: login failed: ${err}\n`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user