diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-02 18:10:17 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2022-06-02 18:10:17 -0400 |
commit | 5f4f28903b2f3428e54ed74417fc06e8eeb58ebf (patch) | |
tree | 6c31807fa3de0bb142ae2bfc7496ee96663a81eb | |
parent | 34b55d206c5048b4abacf68c663261f494c888a2 (diff) | |
download | tanzanite-5f4f28903b2f3428e54ed74417fc06e8eeb58ebf.tar.gz tanzanite-5f4f28903b2f3428e54ed74417fc06e8eeb58ebf.tar.bz2 tanzanite-5f4f28903b2f3428e54ed74417fc06e8eeb58ebf.zip |
feat(errorHandler): ansi colors
-rw-r--r-- | src/commands/admin/channelPermissions.ts | 2 | ||||
-rw-r--r-- | src/commands/dev/eval.ts | 5 | ||||
-rw-r--r-- | src/commands/dev/javascript.ts | 7 | ||||
-rw-r--r-- | src/commands/dev/sh.ts | 16 | ||||
-rw-r--r-- | src/lib/common/typings/CodeBlockLang.ts | 3 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClientUtil.ts | 11 | ||||
-rw-r--r-- | src/lib/extensions/discord.js/BushGuildMember.ts | 2 | ||||
-rw-r--r-- | src/listeners/commands/commandError.ts | 35 | ||||
-rw-r--r-- | src/listeners/contextCommands/contextCommandError.ts | 26 | ||||
-rw-r--r-- | src/listeners/other/promiseRejection.ts | 8 | ||||
-rw-r--r-- | src/listeners/other/uncaughtException.ts | 4 | ||||
-rw-r--r-- | src/listeners/other/warning.ts | 14 |
12 files changed, 72 insertions, 61 deletions
diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts index 15f1260..4091343 100644 --- a/src/commands/admin/channelPermissions.ts +++ b/src/commands/admin/channelPermissions.ts @@ -83,7 +83,7 @@ export default class ChannelPermissionsCommand extends BushCommand { { reason: 'Changing overwrites for mass channel perms command' } ); } catch (e) { - void client.console.error('channelPermissions', util.formatError(e)); + void client.console.error('channelPermissions', util.formatError(e, true)); failedChannels.push(channel); } } diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts index 0f53198..d4c9331 100644 --- a/src/commands/dev/eval.ts +++ b/src/commands/dev/eval.ts @@ -263,11 +263,12 @@ export default class EvalCommand extends BushCommand { if (inputTS) embed.addFields([{ name: ':inbox_tray: Input (typescript)', value: inputTS }]); embed.addFields([{ name: `:inbox_tray: Input${inputTS ? ' (transpiled javascript)' : ''}`, value: inputJS }]); - const output = await this.codeblock(rawResult, 'js', { + const output = await this.codeblock(rawResult, 'ansi', { depth: selDepth ?? 0, showHidden: hidden, showProxy: true, - inspectStrings: !noInspectStrings + inspectStrings: !noInspectStrings, + colors: true }); const methods = !err && showMethods ? await this.codeblock(rawResult, 'ts', { methods: true }) : undefined; diff --git a/src/commands/dev/javascript.ts b/src/commands/dev/javascript.ts index d25b790..373f149 100644 --- a/src/commands/dev/javascript.ts +++ b/src/commands/dev/javascript.ts @@ -60,10 +60,11 @@ export default class JavascriptCommand extends BushCommand { const rawOutput = /^(9\s*?\+\s*?10)|(10\s*?\+\s*?9)$/.test(code) ? '21' : new VM({ eval: true, wasm: true, timeout: 1_000, fixAsync: true }).run(`${code}`); - const output = await util.inspectCleanRedactCodeblock(rawOutput, 'js', { + const output = await util.inspectCleanRedactCodeblock(rawOutput, 'ansi', { depth: args.sel_depth ?? 0, getters: true, - inspectStrings: true + inspectStrings: true, + colors: true }); embed.setTitle(`${util.emojis.successFull} Successfully Evaluated Expression`).setColor(util.colors.success); @@ -75,7 +76,7 @@ export default class JavascriptCommand extends BushCommand { embed.setTitle(`${util.emojis.errorFull} Unable to Evaluate Expression`).setColor(util.colors.error); embed.addFields([ { name: '📥 Input', value: input }, - { name: '📤 Error', value: await util.inspectCleanRedactCodeblock(e, 'js') } + { name: '📤 Error', value: await util.inspectCleanRedactCodeblock(e, 'ansi', { colors: true }) } ]); } diff --git a/src/commands/dev/sh.ts b/src/commands/dev/sh.ts index e071e73..d47ecd2 100644 --- a/src/commands/dev/sh.ts +++ b/src/commands/dev/sh.ts @@ -57,32 +57,32 @@ export default class ShCommand extends BushCommand { await message.util.reply({ embeds: [embed] }); - const pattern = [ + /* const pattern = [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' ].join('|'); function strip(abc: string): string { return abc.replace(new RegExp(pattern, 'g'), ''); - } + } */ try { - const output = await sh(command); - const stdout = strip(clean(output.stdout)); - const stderr = strip(clean(output.stderr)); + const output = await sh(command, { env: { ...process.env, FORCE_COLOR: 'true' } }); + const stdout = /* strip( */ clean(output.stdout); /* ) */ + const stderr = /* strip( */ clean(output.stderr); /* ) */ embed .setTitle(`${util.emojis.successFull} Executed command successfully.`) .setColor(util.colors.success) .spliceFields(1, 1); - if (stdout) embed.addFields([{ name: '📤 stdout', value: await util.codeblock(stdout, 1024, 'json', true) }]); - if (stderr) embed.addFields([{ name: '📤 stderr', value: await util.codeblock(stderr, 1024, 'json', true) }]); + if (stdout) embed.addFields([{ name: '📤 stdout', value: await util.codeblock(stdout, 1024, 'ansi', true) }]); + if (stderr) embed.addFields([{ name: '📤 stderr', value: await util.codeblock(stderr, 1024, 'ansi', true) }]); } catch (e) { embed .setTitle(`${util.emojis.errorFull} An error occurred while executing.`) .setColor(util.colors.error) .spliceFields(1, 1); - embed.addFields([{ name: '📤 Output', value: await util.codeblock(util.formatError(e), 1024, 'js', true) }]); + embed.addFields([{ name: '📤 Output', value: await util.codeblock(util.formatError(e, true), 1024, 'ansi', true) }]); } await message.util.edit({ embeds: [embed] }); } diff --git a/src/lib/common/typings/CodeBlockLang.ts b/src/lib/common/typings/CodeBlockLang.ts index 5a1aeba..d0eb4f3 100644 --- a/src/lib/common/typings/CodeBlockLang.ts +++ b/src/lib/common/typings/CodeBlockLang.ts @@ -307,4 +307,5 @@ export type CodeBlockLang = | 'yml' | 'yaml' | 'zephir' - | 'zep'; + | 'zep' + | 'ansi'; diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index c5a5b30..5c641b6 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -685,9 +685,9 @@ export class BushClientUtil extends ClientUtil { * @param error */ public async handleError(context: string, error: Error) { - await client.console.error(_.camelCase(context), `An error occurred:\n${util.formatError(error)}`, false); + await client.console.error(_.camelCase(context), `An error occurred:\n${util.formatError(error, true)}`, false); await client.console.channelError({ - embeds: [await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error, context })] + embeds: await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error, context }) }); } @@ -1077,17 +1077,18 @@ export class BushClientUtil extends ClientUtil { /** * Formats an error into a string. * @param error The error to format. + * @param colors Whether to use colors in the output. * @returns The formatted error. */ - public formatError(error: Error | any): string { + public formatError(error: Error | any, colors = false): string { if (!error) return error; if (typeof error !== 'object') return String.prototype.toString.call(error); if ( this.getSymbols(error) .map((s) => s.toString()) - .includes('Symbol(util.inspect.custom)') + .includes('Symbol(nodejs.util.inspect.custom)') ) - return error.inspect(); + return this.inspect(error, { colors }); return error.stack; } diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts index 7cc89d2..20a1f60 100644 --- a/src/lib/extensions/discord.js/BushGuildMember.ts +++ b/src/lib/extensions/discord.js/BushGuildMember.ts @@ -373,7 +373,7 @@ export class BushGuildMember extends GuildMember { const muteSuccess = await this.roles .remove(muteRole, `[Unmute] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}`) .catch(async (e) => { - await client.console.warn('muteRoleAddError', util.formatError(e)); + await client.console.warn('muteRoleAddError', util.formatError(e, true)); return false; }); if (!muteSuccess) return unmuteResponse.ACTION_ERROR; diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts index 6d669a1..3768c05 100644 --- a/src/listeners/commands/commandError.ts +++ b/src/listeners/commands/commandError.ts @@ -42,11 +42,12 @@ export default class CommandErrorListener extends BushListener { } }); + client.console.debug(util.getSymbols(error).map((s) => s.toString())); void client.console.error( `${isSlash ? 'slashC' : 'c'}ommandError`, `an error occurred with the <<${command}>> ${isSlash ? 'slash ' : ''}command in <<${channel}>> triggered by <<${ message?.author?.tag - }>>:\n${util.formatError(error)})}`, + }>>:\n${util.formatError(error, true)})}`, false ); @@ -60,7 +61,7 @@ export default class CommandErrorListener extends BushListener { type: 'command-log' }); - void client.logger.channelError({ embeds: [errorEmbed] }); + void client.logger.channelError({ embeds: errorEmbed }); if (message) { if (!client.config.owners.includes(message.author.id)) { @@ -68,14 +69,14 @@ export default class CommandErrorListener extends BushListener { ...options, type: 'command-user' }); - void message.util?.send({ embeds: [errorUserEmbed] }).catch(() => null); + void message.util?.send({ embeds: errorUserEmbed }).catch(() => null); } else { const errorDevEmbed = CommandErrorListener._generateErrorEmbed({ ...options, type: 'command-dev' }); - void message.util?.send({ embeds: [errorDevEmbed] }).catch(() => null); + void message.util?.send({ embeds: errorDevEmbed }).catch(() => null); } } } catch (e) { @@ -95,7 +96,7 @@ export default class CommandErrorListener extends BushListener { channel?: string; } | { error: Error | any; type: 'uncaughtException' | 'unhandledRejection'; context?: string } - ): Promise<EmbedBuilder> { + ): Promise<EmbedBuilder[]> { const _haste = CommandErrorListener.getErrorHaste(options.error); const _stack = CommandErrorListener.getErrorStack(options.error); const [haste, stack] = await Promise.all([_haste, _stack]); @@ -123,10 +124,10 @@ export default class CommandErrorListener extends BushListener { haste: string[]; stack: string; } - ): EmbedBuilder { - const embed = new EmbedBuilder().setColor(util.colors.error).setTimestamp(); + ): EmbedBuilder[] { + const embeds = [new EmbedBuilder().setColor(util.colors.error)]; if (options.type === 'command-user') { - return embed + embeds[0] .setTitle('An Error Occurred') .setDescription( `Oh no! ${ @@ -134,7 +135,9 @@ export default class CommandErrorListener extends BushListener { ? `While running the ${options.isSlash ? 'slash ' : ''}command ${util.format.input(options.command.id)}, a` : 'A' }n error occurred. Please give the developers code ${util.format.input(`${options.errorNum}`)}.` - ); + ) + .setTimestamp(); + return embeds; } const description: string[] = []; @@ -150,18 +153,18 @@ export default class CommandErrorListener extends BushListener { description.push(...options.haste); - embed.addFields([{ name: 'Stack Trace', value: options.stack.substring(0, 1024) }]); - if (description.length) embed.setDescription(description.join('\n').substring(0, 4000)); + embeds.push(new EmbedBuilder().setColor(util.colors.error).setTimestamp().setDescription(options.stack.substring(0, 4000))); + if (description.length) embeds[0].setDescription(description.join('\n').substring(0, 4000)); if (options.type === 'command-dev' || options.type === 'command-log') - embed.setTitle(`${options.isSlash ? 'Slash ' : ''}CommandError #${util.format.input(`${options.errorNum}`)}`); + embeds[0].setTitle(`${options.isSlash ? 'Slash ' : ''}CommandError #${util.format.input(`${options.errorNum}`)}`); else if (options.type === 'uncaughtException') - embed.setTitle(`${options.context ? `[${Formatters.bold(options.context)}] An Error Occurred` : 'Uncaught Exception'}`); + embeds[0].setTitle(`${options.context ? `[${Formatters.bold(options.context)}] An Error Occurred` : 'Uncaught Exception'}`); else if (options.type === 'unhandledRejection') - embed.setTitle( + embeds[0].setTitle( `${options.context ? `[${Formatters.bold(options.context)}] An Error Occurred` : 'Unhandled Promise Rejection'}` ); - return embed; + return embeds; } public static async getErrorHaste(error: Error | any): Promise<string[]> { @@ -229,7 +232,7 @@ export default class CommandErrorListener extends BushListener { } public static async getErrorStack(error: Error | any): Promise<string> { - return await util.inspectCleanRedactCodeblock(util.formatError(error), 'js'); + return await util.inspectCleanRedactCodeblock(error /* util.formatError(error, true) */, 'ansi', { colors: true }, 4000); } } diff --git a/src/listeners/contextCommands/contextCommandError.ts b/src/listeners/contextCommands/contextCommandError.ts index 45e1114..e020f2b 100644 --- a/src/listeners/contextCommands/contextCommandError.ts +++ b/src/listeners/contextCommands/contextCommandError.ts @@ -44,7 +44,7 @@ export default class ContextCommandErrorListener extends BushListener { `contextCommandError`, `an error occurred with the <<${command}>> context command in <<${channel}>> triggered by <<${ interaction?.user?.tag - }>>:\n${util.formatError(error)}`, + }>>:\n${util.formatError(error, true)}`, false ); @@ -58,7 +58,7 @@ export default class ContextCommandErrorListener extends BushListener { type: 'command-log' }); - void client.logger.channelError({ embeds: [errorEmbed] }); + void client.logger.channelError({ embeds: errorEmbed }); if (interaction) { if (!client.config.owners.includes(interaction.user.id)) { @@ -66,14 +66,14 @@ export default class ContextCommandErrorListener extends BushListener { ...options, type: 'command-user' }); - void interaction?.reply({ embeds: [errorUserEmbed] }).catch(() => null); + void interaction?.reply({ embeds: errorUserEmbed }).catch(() => null); } else { const errorDevEmbed = this._generateErrorEmbed({ ...options, type: 'command-dev' }); - void interaction?.reply({ embeds: [errorDevEmbed] }).catch(() => null); + void interaction?.reply({ embeds: errorDevEmbed }).catch(() => null); } } } catch (e) { @@ -90,16 +90,18 @@ export default class ContextCommandErrorListener extends BushListener { channel?: string; haste: string[]; stack: string; - }): EmbedBuilder { - const embed = new EmbedBuilder().setColor(util.colors.error).setTimestamp(); + }): EmbedBuilder[] { + const embeds = [new EmbedBuilder().setColor(util.colors.error)]; if (options.type === 'command-user') { - return embed + embeds[0] .setTitle('An Error Occurred') .setDescription( `Oh no! ${ options.command ? `While running the command ${util.format.input(options.command.id)}, a` : 'A' }n error occurred. Please give the developers code ${util.format.input(`${options.errorNum}`)}.` - ); + ) + .setTimestamp(); + return embeds; } const description: string[] = []; @@ -113,11 +115,11 @@ export default class ContextCommandErrorListener extends BushListener { description.push(...options.haste); - embed.addFields([{ name: 'Stack Trace', value: options.stack.substring(0, 1024) }]); - if (description.length) embed.setDescription(description.join('\n').substring(0, 4000)); + embeds.push(new EmbedBuilder().setColor(util.colors.error).setTimestamp().setDescription(options.stack.substring(0, 4000))); + if (description.length) embeds[0].setDescription(description.join('\n').substring(0, 4000)); if (options.type === 'command-dev' || options.type === 'command-log') - embed.setTitle(`ContextCommandError #${util.format.input(`${options.errorNum}`)}`); - return embed; + embeds[0].setTitle(`ContextCommandError #${util.format.input(`${options.errorNum}`)}`); + return embeds; } } diff --git a/src/listeners/other/promiseRejection.ts b/src/listeners/other/promiseRejection.ts index 270db46..1157556 100644 --- a/src/listeners/other/promiseRejection.ts +++ b/src/listeners/other/promiseRejection.ts @@ -21,10 +21,14 @@ export default class PromiseRejectionListener extends BushListener { level: Severity.Error }); - void client.console.error('promiseRejection', `An unhanded promise rejection occurred:\n${util.formatError(error)}`, false); + void client.console.error( + 'promiseRejection', + `An unhanded promise rejection occurred:\n${util.formatError(error, true)}`, + false + ); if (!error.message.includes('reason: getaddrinfo ENOTFOUND canary.discord.com')) void client.console.channelError({ - embeds: [await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error })] + embeds: await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error }) }); } } diff --git a/src/listeners/other/uncaughtException.ts b/src/listeners/other/uncaughtException.ts index b12f76d..4a66515 100644 --- a/src/listeners/other/uncaughtException.ts +++ b/src/listeners/other/uncaughtException.ts @@ -20,9 +20,9 @@ export default class UncaughtExceptionListener extends BushListener { level: Severity.Error }); - void client.console.error('uncaughtException', `An uncaught exception occurred:\n${util.formatError(error)}`, false); + void client.console.error('uncaughtException', `An uncaught exception occurred:\n${util.formatError(error, true)}`, false); void client.console.channelError({ - embeds: [await CommandErrorListener.generateErrorEmbed({ type: 'uncaughtException', error: error })] + embeds: await CommandErrorListener.generateErrorEmbed({ type: 'uncaughtException', error: error }) }); } } diff --git a/src/listeners/other/warning.ts b/src/listeners/other/warning.ts index 2412221..8e1fdf6 100644 --- a/src/listeners/other/warning.ts +++ b/src/listeners/other/warning.ts @@ -17,13 +17,11 @@ export default class WarningListener extends BushListener { level: Severity.Warning }); - void client.console.warn('warning', `A warning occurred:\n${util.formatError(error)}`, false); - void client.console.channelError({ - embeds: [ - (await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error })) - .setColor(util.colors.warn) - .setTitle('A Warning Occurred') - ] - }); + void client.console.warn('warning', `A warning occurred:\n${util.formatError(error, true)}`, false); + + const embeds = await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error }); + embeds[0].setColor(util.colors.warn).setTitle('A Warning Occurred'); + + void client.console.channelError({ embeds }); } } |