From cec565232ba7655429ec0fa2825f9487356b22e3 Mon Sep 17 00:00:00 2001 From: NorySight <114584253+GrishMahat@users.noreply.github.com> Date: Tue, 16 Jul 2024 01:34:00 +0545 Subject: [PATCH] fix bug --- src/buttons/requestUserInfoBtn.js | 29 +++-- src/events/validations/buttonValidator.js | 16 +-- src/handlers/errorHandler.js | 122 ++++++++++++++++------ src/index.js | 14 ++- 4 files changed, 116 insertions(+), 65 deletions(-) diff --git a/src/buttons/requestUserInfoBtn.js b/src/buttons/requestUserInfoBtn.js index 0989eb6..2cb9268 100644 --- a/src/buttons/requestUserInfoBtn.js +++ b/src/buttons/requestUserInfoBtn.js @@ -12,9 +12,8 @@ export default { run: async (client, interaction) => { try { - const { guild, member } = interaction; + const { guild, member, channel } = interaction; - // Defer the interaction immediately to prevent timeout await interaction.deferReply(); // Get the ticket setup configuration @@ -37,20 +36,22 @@ export default { }); } - // Get user ticket information - const ticket = await ticketSchema.findOne({ + // Get the ticket information + const sticket = await ticketSchema.findOne({ guildID: guild.id, - ticketMemberID: interaction.user.id, + ticketChannelID: channel.id, + closed: false, }); - if (!ticket) { + + if (!sticket) { return await interaction.editReply({ - content: 'User not found. Please specify a valid user.', + content: 'This ticket is not valid or is closed.', ephemeral: true, }); } const user = await guild.members - .fetch(ticket.ticketMemberID) + .fetch(sticket.ticketMemberID) .catch(() => null); if (!user) { return await interaction.editReply({ @@ -67,13 +68,13 @@ export default { if (!tickets || tickets.length === 0) { return await interaction.editReply({ - content: 'This user has no tickets.', + content: 'This user has no closed tickets.', ephemeral: true, }); } // Format tickets into pages - const pages = tickets.map((ticket, index) => { + const pages = tickets.map((ticket) => { const claimedBy = ticket.claimedBy ? `<@${ticket.claimedBy}>` : 'Unclaimed'; @@ -103,16 +104,12 @@ export default { }, { name: '⏳ Open Duration', - value: ``, + value: ``, inline: true, }, { name: '🔒 Closed At', - value: ``, + value: ``, inline: true, }, { diff --git a/src/events/validations/buttonValidator.js b/src/events/validations/buttonValidator.js index 70c4a7a..3f5e732 100644 --- a/src/events/validations/buttonValidator.js +++ b/src/events/validations/buttonValidator.js @@ -39,21 +39,7 @@ const handleButton = async (client, errorHandler, interaction) => { const { customId } = interaction; const button = buttons.get(customId); - if (!button) { - errorHandler.handleError(new Error(`Unknown button: ${customId}`), { - type: 'unknownButton', - buttonId: customId, - userId: interaction.user.id, - guildId: interaction.guild.id, - }); - return sendEmbedReply( - interaction, - mConfig.embedColorError, - 'This button is not recognized.', - true - ); - } - + if (!button) return; const { developersId, testServerId } = config; // Check if the button is developer-only diff --git a/src/handlers/errorHandler.js b/src/handlers/errorHandler.js index 7ec00b9..75bf8ba 100644 --- a/src/handlers/errorHandler.js +++ b/src/handlers/errorHandler.js @@ -1,4 +1,9 @@ -import { WebhookClient, EmbedBuilder, Events, DiscordAPIError } from 'discord.js'; +import { + WebhookClient, + EmbedBuilder, + Events, + DiscordAPIError, +} from 'discord.js'; import Bottleneck from 'bottleneck'; class DiscordBotErrorHandler { @@ -10,14 +15,18 @@ class DiscordBotErrorHandler { retryAttempts: 3, retryDelay: 1000, rateLimit: { maxConcurrent: 1, minTime: 2000 }, - clientName: 'unknown client', + clientName: 'nory', ...config, }; if (!this.config.webhookUrl) { - console.error('ERROR_WEBHOOK_URL is not set in the environment variables'); + console.error( + 'ERROR_WEBHOOK_URL is not set in the environment variables' + ); } else { - this.webhookClient = new WebhookClient({ url: this.config.webhookUrl }); + this.webhookClient = new WebhookClient({ + url: this.config.webhookUrl, + }); } this.errorCache = new Map(); @@ -33,19 +42,28 @@ class DiscordBotErrorHandler { console.error('Discord client is not provided'); return; } - this.config.clientName = this.client.user?.username || this.config.clientName; + this.config.clientName = + this.client.user?.username || this.config.clientName; this.setupEventListeners(); this.client.ws.on('error', this.handleWebSocketError.bind(this)); } setupEventListeners() { - this.client.on(Events.Error, (error) => this.handleError(error, { type: 'clientError' })); - this.client.on(Events.Warn, (info) => this.handleError(new Error(info), { - type: 'clientWarning', - severity: 'Warning', - })); - process.on('unhandledRejection', (reason) => this.handleError(reason, { type: 'unhandledRejection' })); - process.on('uncaughtException', (error) => this.handleError(error, { type: 'uncaughtException' })); + this.client.on(Events.Error, (error) => + this.handleError(error, { type: 'clientError' }) + ); + this.client.on(Events.Warn, (info) => + this.handleError(new Error(info), { + type: 'clientWarning', + severity: 'Warning', + }) + ); + process.on('unhandledRejection', (reason) => + this.handleError(reason, { type: 'unhandledRejection' }) + ); + process.on('uncaughtException', (error) => + this.handleError(error, { type: 'uncaughtException' }) + ); } handleWebSocketError(error) { @@ -64,7 +82,10 @@ class DiscordBotErrorHandler { cleanStackTrace(error, limit = 10) { const stack = (error.stack || '') .split('\n') - .filter(line => !line.includes('node_modules') && !line.includes('timers.js')) + .filter( + (line) => + !line.includes('node_modules') && !line.includes('timers.js') + ) .slice(0, limit) .join('\n'); @@ -82,7 +103,11 @@ class DiscordBotErrorHandler { if (guildId) { try { const guild = await this.client.guilds.fetch(guildId); - return { id: guild.id, name: guild.name, memberCount: guild.memberCount }; + return { + id: guild.id, + name: guild.name, + memberCount: guild.memberCount, + }; } catch (error) { console.error('Failed to fetch guild context:', error); } @@ -112,16 +137,26 @@ class DiscordBotErrorHandler { if (message.includes('timeout')) return 'Timeout Error'; if (message.includes('not found')) return 'Not Found Error'; if (message.includes('database')) return 'Database Error'; - if (message.includes('auth') || message.includes('token')) return 'Authentication Error'; - if (message.includes('connect') || message.includes('connection')) return 'Connection Error'; - if (message.includes('parse') || message.includes('syntax')) return 'Parsing Error'; + if (message.includes('auth') || message.includes('token')) + return 'Authentication Error'; + if (message.includes('connect') || message.includes('connection')) + return 'Connection Error'; + if (message.includes('parse') || message.includes('syntax')) + return 'Parsing Error'; if (message.includes('memory')) return 'Memory Error'; - if (message.includes('disk') || message.includes('storage')) return 'Storage Error'; + if (message.includes('disk') || message.includes('storage')) + return 'Storage Error'; if (message.includes('gateway')) return 'Gateway Error'; if (message.includes('unexpected token')) return 'Unexpected Token Error'; - if (message.includes('invalid form body')) return 'Invalid Form Body Error'; - if (message.includes('unknown interaction')) return 'Unknown Interaction Error'; - if (error instanceof Error && error.message === "Unhandled 'error' event emitted") return 'WebSocket Error'; + if (message.includes('invalid form body')) + return 'Invalid Form Body Error'; + if (message.includes('unknown interaction')) + return 'Unknown Interaction Error'; + if ( + error instanceof Error && + error.message === "Unhandled 'error' event emitted" + ) + return 'WebSocket Error'; return 'Unknown Error'; } @@ -131,7 +166,11 @@ class DiscordBotErrorHandler { if ([10008, 10003].includes(error.code)) return 'Major'; return 'Moderate'; } - if (error instanceof Error && error.message === "Unhandled 'error' event emitted") return 'Major'; + if ( + error instanceof Error && + error.message === "Unhandled 'error' event emitted" + ) + return 'Major'; if (error.critical) return 'Critical'; if (error instanceof TypeError) return 'Warning'; if (error.message.includes('rate limit')) return 'Major'; @@ -181,7 +220,9 @@ class DiscordBotErrorHandler { async processErrorQueue() { while (this.errorQueue.length > 0) { const errorDetails = this.errorQueue.shift(); - await this.limiter.schedule(() => this.sendErrorToWebhook(errorDetails)); + await this.limiter.schedule(() => + this.sendErrorToWebhook(errorDetails) + ); } this.processingQueue = false; } @@ -194,12 +235,26 @@ class DiscordBotErrorHandler { .setTitle(`${errorDetails.category} - ${errorDetails.severity}`) .setDescription(`\`\`\`${errorDetails.message}\`\`\``) .addFields( - { name: 'Stack Trace', value: `\`\`\`${errorDetails.stackTrace}\`\`\``, inline: false }, - { name: 'Context', value: `\`\`\`json\n${JSON.stringify(errorDetails.context, null, 2)}\`\`\``, inline: false }, - { name: 'Performance', value: `\`\`\`json\n${JSON.stringify(await errorDetails.performance, null, 2)}\`\`\``, inline: false } + { + name: 'Stack Trace', + value: `\`\`\`${errorDetails.stackTrace}\`\`\``, + inline: false, + }, + { + name: 'Context', + value: `\`\`\`json\n${JSON.stringify(errorDetails.context, null, 2)}\`\`\``, + inline: false, + }, + { + name: 'Performance', + value: `\`\`\`json\n${JSON.stringify(await errorDetails.performance, null, 2)}\`\`\``, + inline: false, + } ) .setTimestamp(new Date(errorDetails.timestamp)) - .setFooter({ text: `Environment: ${errorDetails.environment.nodeVersion} | Client: ${errorDetails.environment.clientName}` }); + .setFooter({ + text: `Environment: ${errorDetails.environment.nodeVersion} | Client: ${errorDetails.environment.clientName}`, + }); await this.webhookClient.send({ content: `New ${errorDetails.severity} error reported`, @@ -207,9 +262,14 @@ class DiscordBotErrorHandler { }); return; } catch (err) { - console.error(`Failed to send error to webhook (attempt ${attempt + 1}):`, err); + console.error( + `Failed to send error to webhook (attempt ${attempt + 1}):`, + err + ); if (attempt < this.config.retryAttempts - 1) { - await new Promise(resolve => setTimeout(resolve, this.config.retryDelay)); + await new Promise((resolve) => + setTimeout(resolve, this.config.retryDelay) + ); } } } @@ -237,7 +297,9 @@ class DiscordBotErrorHandler { const fullContext = await this.captureContext(context); return { message: error.message || 'Unknown error', - stackTrace: error.stack ? this.cleanStackTrace(error) : 'No stack trace available', + stackTrace: error.stack + ? this.cleanStackTrace(error) + : 'No stack trace available', category: this.determineErrorCategory(error), severity: this.determineErrorSeverity(error), context: fullContext, diff --git a/src/index.js b/src/index.js index 8af181a..aec93ea 100644 --- a/src/index.js +++ b/src/index.js @@ -6,22 +6,28 @@ import DiscordBotErrorHandler from './handlers/errorHandler.js'; const checkEnvVariables = () => { if (!process.env.TOKEN) { - console.error('ERROR: TOKEN is not defined in the environment variables.'); + console.error( + 'ERROR: TOKEN is not defined in the environment variables.' + ); process.exit(1); } if (!process.env.MONGODB_TOKEN) { - console.error('ERROR: MONGODB_TOKEN is not defined in the environment variables.'); + console.error( + 'ERROR: MONGODB_TOKEN is not defined in the environment variables.' + ); process.exit(1); } if (!process.env.GITHUB_TOKEN) { - console.error('ERROR: GITHUB_TOKEN is not defined in the environment variables.'); + console.error( + 'ERROR: GITHUB_TOKEN is not defined in the environment variables.' + ); process.exit(1); } }; const main = async () => { checkEnvVariables(); -w + w; let eventHandler; try { const module = await import('./handlers/eventHandler.js');