diff --git a/src/clients/discord/discord.module.ts b/src/clients/discord/discord.module.ts index ba703a3..d9a2e5f 100644 --- a/src/clients/discord/discord.module.ts +++ b/src/clients/discord/discord.module.ts @@ -1,5 +1,7 @@ +import { registerFilterGlobally } from '@discord-nestjs/core'; import { Module } from '@nestjs/common'; import { OnModuleDestroy } from '@nestjs/common/interfaces/hooks'; +import { CommandExecutionError } from '../../middleware/command-execution-filter'; import { PlaybackModule } from '../../playback/playback.module'; import { DiscordConfigService } from './discord.config.service'; import { DiscordMessageService } from './discord.message.service'; @@ -8,7 +10,15 @@ import { DiscordVoiceService } from './discord.voice.service'; @Module({ imports: [PlaybackModule], controllers: [], - providers: [DiscordConfigService, DiscordVoiceService, DiscordMessageService], + providers: [ + DiscordConfigService, + DiscordVoiceService, + DiscordMessageService, + { + provide: registerFilterGlobally(), + useClass: CommandExecutionError, + }, + ], exports: [DiscordConfigService, DiscordVoiceService, DiscordMessageService], }) export class DiscordClientModule implements OnModuleDestroy { diff --git a/src/middleware/command-execution-filter.ts b/src/middleware/command-execution-filter.ts new file mode 100644 index 0000000..908ee73 --- /dev/null +++ b/src/middleware/command-execution-filter.ts @@ -0,0 +1,57 @@ +import { + Catch, + DiscordArgumentMetadata, + DiscordExceptionFilter, + On, +} from '@discord-nestjs/core'; +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + CommandInteraction, + ComponentBuilder, + Events, + Interaction, +} from 'discord.js'; +import { DiscordMessageService } from '../clients/discord/discord.message.service'; +import { Constants } from '../utils/constants'; + +@Catch(Error) +export class CommandExecutionError implements DiscordExceptionFilter { + constructor(private readonly discordMessageService: DiscordMessageService) {} + + async catch( + exception: Error, + metadata: DiscordArgumentMetadata, + ): Promise { + console.log(metadata); + const interaction: CommandInteraction = metadata.eventArgs[0]; + + if (!interaction.isCommand()) { + return; + } + + console.log(exception); + + const row = new ActionRowBuilder().addComponents( + new ButtonBuilder() + .setLabel('Report this issue') + .setStyle(ButtonStyle.Link) + .setURL( + Constants.Links.BugReport( + `[Bug]: ${exception.name} - ${exception.message}`, + ).toString(), + ), + ); + + interaction.reply({ + embeds: [ + this.discordMessageService.buildErrorMessage({ + title: 'An unexpected exception occured', + description: `Oh no! This isn't supposed to happen. Something did not went right during the execution of your command.\n\nPlease check if there is any update available. If not, please check on ${Constants.Links.Issues} if this problem has already been reported. If not, please report this problem using the button below.\n\n**Debug Information** (please include in your report):\n\`\`\`${exception.stack}\`\`\``, + }), + ], + components: [row], + }); + } +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 95a9b69..766a0b1 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -5,8 +5,13 @@ export const Constants = { }, Links: { SourceCode: 'https://github.com/manuel-rw/jellyfin-discord-music-bot/', + Issues: 'https://github.com/manuel-rw/jellyfin-discord-music-bot/issues/', ReportIssue: 'https://github.com/manuel-rw/jellyfin-discord-music-bot/issues/new/choose', + BugReport: (title) => + new URL( + `https://github.com/manuel-rw/jellyfin-discord-music-bot/issues/new?assignees=&labels=&template=bug_report.md&title=${title}`, + ), }, Design: { InvisibleSpace: '\u1CBC',