connection loss protection
This commit is contained in:
68
index.js
68
index.js
@@ -56,18 +56,15 @@ client.on(Events.GuildMemberAdd, async (member) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Log in
|
||||
// Catch library/client errors to prevent unhandled 'error' events from crashing the process
|
||||
// Log in and add reconnect/resiliency logic
|
||||
client.on('error', (err) => {
|
||||
console.error('Client error:', err);
|
||||
});
|
||||
|
||||
// Some libraries emit shard-specific errors — log them for diagnostics
|
||||
client.on('shardError', (err) => {
|
||||
console.error('Shard error:', err);
|
||||
});
|
||||
|
||||
// Global handlers to capture unexpected problems and provide diagnostics
|
||||
process.on('uncaughtException', (err) => {
|
||||
console.error('Uncaught exception:', err);
|
||||
});
|
||||
@@ -76,4 +73,65 @@ process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
||||
});
|
||||
|
||||
client.login(BOT_TOKEN);
|
||||
// Reconnect/backoff helpers
|
||||
let reconnectAttempts = 0;
|
||||
let isConnecting = false;
|
||||
const MAX_BACKOFF = 30000; // 30s
|
||||
|
||||
async function connectWithRetry() {
|
||||
if (isConnecting) return;
|
||||
isConnecting = true;
|
||||
try {
|
||||
// If the library provides a destroy/logout method, try to clean up first
|
||||
if (typeof client.destroy === 'function') {
|
||||
try {
|
||||
client.destroy();
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
await client.login(BOT_TOKEN);
|
||||
reconnectAttempts = 0;
|
||||
console.log('Successfully connected.');
|
||||
} catch (err) {
|
||||
reconnectAttempts += 1;
|
||||
const delay = Math.min(MAX_BACKOFF, 1000 * Math.pow(2, Math.min(reconnectAttempts, 5)));
|
||||
console.error(`Login attempt ${reconnectAttempts} failed:`, err);
|
||||
console.log(`Retrying in ${delay}ms...`);
|
||||
setTimeout(() => {
|
||||
isConnecting = false;
|
||||
connectWithRetry();
|
||||
}, delay);
|
||||
} finally {
|
||||
isConnecting = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for common disconnect-like events and trigger reconnect attempts.
|
||||
// Different client implementations emit different event names; guard each with a check.
|
||||
try {
|
||||
client.on('disconnect', (event) => {
|
||||
console.warn('Client disconnected:', event);
|
||||
setTimeout(connectWithRetry, 1000);
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
client.on('close', (code, reason) => {
|
||||
console.warn('Connection closed:', code, reason);
|
||||
setTimeout(connectWithRetry, 1000);
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
// Periodic health check: if client isn't ready, try reconnecting.
|
||||
setInterval(() => {
|
||||
const healthy = client && client.user && client.user.username;
|
||||
if (!healthy) {
|
||||
console.warn('Health check: client not ready, attempting reconnect...');
|
||||
connectWithRetry();
|
||||
}
|
||||
}, 30 * 1000);
|
||||
|
||||
// Start initial connection attempt
|
||||
connectWithRetry();
|
||||
|
||||
Reference in New Issue
Block a user