diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/config/config.ts | 6 | ||||
-rw-r--r-- | src/commands/config/features.ts | 6 | ||||
-rw-r--r-- | src/commands/info/guildInfo.ts | 2 | ||||
-rw-r--r-- | src/commands/info/help.ts | 3 | ||||
-rw-r--r-- | src/commands/info/links.ts | 2 | ||||
-rw-r--r-- | src/commands/info/snowflake.ts | 2 | ||||
-rw-r--r-- | src/commands/info/userInfo.ts | 6 | ||||
-rw-r--r-- | src/commands/leveling/leaderboard.ts | 13 | ||||
-rw-r--r-- | src/commands/leveling/level.ts | 12 | ||||
-rw-r--r-- | src/commands/moderation/modlog.ts | 2 | ||||
-rw-r--r-- | src/commands/moderation/unban.ts | 2 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClient.ts | 15 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClientUtil.ts | 56 | ||||
-rw-r--r-- | src/lib/extensions/discord.js/BushClientEvents.d.ts | 5 | ||||
-rw-r--r-- | src/lib/extensions/discord.js/BushGuildMember.ts | 5 | ||||
-rw-r--r-- | src/lib/models/ActivePunishment.ts | 2 | ||||
-rw-r--r-- | src/lib/utils/BushLogger.ts | 2 | ||||
-rw-r--r-- | src/listeners/message/autoThread.ts | 15 | ||||
-rw-r--r-- | src/listeners/other/promiseRejection.ts | 7 | ||||
-rw-r--r-- | src/listeners/other/uncaughtException.ts | 7 | ||||
-rw-r--r-- | src/listeners/other/warning.ts | 22 |
21 files changed, 141 insertions, 51 deletions
diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts index 6e7373c..3f1fc8c 100644 --- a/src/commands/config/config.ts +++ b/src/commands/config/config.ts @@ -240,10 +240,8 @@ export default class SettingsCommand extends BushCommand { } } const collector = msg.createMessageComponentCollector({ - channel: message.channel ?? undefined, - guild: message.guild, - message: message as Message, - time: 300_000 + time: 300_000, + filter: (i) => i.guildId === message.guildId && i.message.id === message.id }); collector.on('collect', async (interaction: MessageComponentInteraction) => { diff --git a/src/commands/config/features.ts b/src/commands/config/features.ts index 8010ab9..743b243 100644 --- a/src/commands/config/features.ts +++ b/src/commands/config/features.ts @@ -28,11 +28,9 @@ export default class FeaturesCommand extends BushCommand { const components = this.generateComponents(guildFeaturesArr, false); const msg = (await message.util.reply({ embeds: [featureEmbed], components: [components] })) as Message; const collector = msg.createMessageComponentCollector({ - channel: message.channel ?? undefined, - guild: message.guild, componentType: 'SELECT_MENU', - message: message as Message, - time: 300_000 + time: 300_000, + filter: (i) => i.guildId === message.guildId && i.message.id === message.id }); collector.on('collect', async (interaction: SelectMenuInteraction) => { diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts index f70b741..f1db783 100644 --- a/src/commands/info/guildInfo.ts +++ b/src/commands/info/guildInfo.ts @@ -105,7 +105,7 @@ export default class GuildInfoCommand extends BushCommand { guildAbout.push( `**Owner:** ${guild.members.cache.get(guild.ownerId)?.user.tag}`, - `**Created** ${guild.createdAt.toLocaleString()} (${util.dateDelta(guild.createdAt)})`, + `**Created** ${util.timestamp(guild.createdAt)} (${util.dateDelta(guild.createdAt)})`, `**Members:** ${guild.memberCount.toLocaleString() ?? 0} (${util.emojis.onlineCircle} ${ guild.approximatePresenceCount?.toLocaleString() ?? 0 }, ${util.emojis.offlineCircle} ${(guild.memberCount - (guild.approximatePresenceCount ?? 0)).toLocaleString() ?? 0})`, diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts index 1338f8a..8c97ba8 100644 --- a/src/commands/info/help.ts +++ b/src/commands/info/help.ts @@ -1,7 +1,6 @@ import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js'; import packageDotJSON from '../../../package.json'; - export default class HelpCommand extends BushCommand { public constructor() { super('help', { @@ -61,7 +60,7 @@ export default class HelpCommand extends BushCommand { label: 'Invite Me', url: `https://discord.com/api/oauth2/authorize?client_id=${ client.user!.id - }&permissions=2147483647&scope=bot%20applications.commands` + }&permissions=5368709119918&scope=bot%20applications.commands` }) ); } diff --git a/src/commands/info/links.ts b/src/commands/info/links.ts index 29152d9..b3a762a 100644 --- a/src/commands/info/links.ts +++ b/src/commands/info/links.ts @@ -27,7 +27,7 @@ export default class LinksCommand extends BushCommand { label: 'Invite Me', url: `https://discord.com/api/oauth2/authorize?client_id=${ client.user!.id - }&permissions=2147483647&scope=bot%20applications.commands` + }&permissions=5368709119918&scope=bot%20applications.commands` }), new MessageButton({ style: 'LINK', diff --git a/src/commands/info/snowflake.ts b/src/commands/info/snowflake.ts index 8d6129b..df11bce 100644 --- a/src/commands/info/snowflake.ts +++ b/src/commands/info/snowflake.ts @@ -139,7 +139,7 @@ export default class SnowflakeCommand extends BushCommand { const deconstructedSnowflake: DeconstructedSnowflake = SnowflakeUtil.deconstruct(snowflake); const snowflakeInfo = [ `**Timestamp:** ${deconstructedSnowflake.timestamp}`, - `**Created:** ${deconstructedSnowflake.date.toLocaleString()}`, + `**Created:** ${util.timestamp(deconstructedSnowflake.date)}`, `**Worker ID:** ${deconstructedSnowflake.workerId}`, `**Process ID:** ${deconstructedSnowflake.processId}`, `**Increment:** ${deconstructedSnowflake.increment}` diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts index 745dcf0..98ef3ae 100644 --- a/src/commands/info/userInfo.ts +++ b/src/commands/info/userInfo.ts @@ -85,11 +85,11 @@ export default class UserInfoCommand extends BushCommand { else if (member?.permissions.has('ADMINISTRATOR')) emojis.push(client.consts.mappings.otherEmojis.ADMIN); if (member?.premiumSinceTimestamp) emojis.push(client.consts.mappings.otherEmojis.BOOSTER); - const createdAt = user.createdAt.toLocaleString(), + const createdAt = util.timestamp(user.createdAt), createdAtDelta = util.dateDelta(user.createdAt), - joinedAt = member?.joinedAt?.toLocaleString(), + joinedAt = util.timestamp(member?.joinedAt), joinedAtDelta = member && member.joinedAt ? util.dateDelta(member.joinedAt, 2) : undefined, - premiumSince = member?.premiumSince?.toLocaleString(), + premiumSince = util.timestamp(member?.premiumSince), premiumSinceDelta = member && member.premiumSince ? util.dateDelta(member.premiumSince, 2) : undefined; // General Info diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts index 953a6c5..4fb1765 100644 --- a/src/commands/leveling/leaderboard.ts +++ b/src/commands/leveling/leaderboard.ts @@ -41,8 +41,19 @@ export default class LeaderboardCommand extends BushCommand { if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`); if (!(await message.guild.hasFeature('leveling'))) return await message.util.reply( - `${util.emojis.error} This command can only be run in commands with the leveling feature enabled.` + `${util.emojis.error} This command can only be run in servers with the leveling feature enabled.${ + message.member?.permissions.has('MANAGE_GUILD') + ? ` You can toggle features using the \`${ + message.util.isSlash + ? '/' + : client.config.isDevelopment + ? 'dev ' + : message.util.parsed?.prefix ?? client.config.prefix + }features\` command.` + : '' + }` ); + const ranks = (await Level.findAll({ where: { guild: message.guild.id } })).sort((a, b) => b.xp - a.xp); const mapedRanks = ranks.map( (val, index) => `\`${index + 1}\` <@${val.user}> - Level ${val.level} (${val.xp.toLocaleString()} xp)` diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts index f14c005..33ad705 100644 --- a/src/commands/leveling/level.ts +++ b/src/commands/leveling/level.ts @@ -132,7 +132,17 @@ export default class LevelCommand extends BushCommand { if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`); if (!(await message.guild.hasFeature('leveling'))) return await message.util.reply( - `${util.emojis.error} This command can only be run in commands with the leveling feature enabled.` + `${util.emojis.error} This command can only be run in servers with the leveling feature enabled.${ + message.member?.permissions.has('MANAGE_GUILD') + ? ` You can toggle features using the \`${ + message.util.isSlash + ? '/' + : client.config.isDevelopment + ? 'dev ' + : message.util.parsed?.prefix ?? client.config.prefix + }features\` command.` + : '' + }` ); const user = args.user ?? message.author; try { diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index d1a3900..c72ff39 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -53,7 +53,7 @@ export default class ModlogCommand extends BushCommand { modLog.push(`**Moderator**: <@!${log.moderator}>`); if (log.duration) modLog.push(`**Duration**: ${util.humanizeDuration(log.duration)}`); modLog.push(`**Reason**: ${trim(log.reason ?? 'No Reason Specified.')}`); - modLog.push(`**Date**: ${log.createdAt.toLocaleString()}`); + modLog.push(`**Date**: ${util.timestamp(log.createdAt)}`); if (log.evidence) modLog.push(`**Evidence:** ${trim(log.evidence)}`); return modLog.join(`\n`); } diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts index 5025ede..a319ff9 100644 --- a/src/commands/moderation/unban.ts +++ b/src/commands/moderation/unban.ts @@ -76,7 +76,7 @@ export default class UnbanCommand extends BushCommand { case 'error creating modlog entry': return `${util.emojis.error} While unbanning **${user.tag}**, there was an error creating a modlog entry, please report this to my developers.`; case 'user not banned': - return `${util.emojis.warn} **${user.tag}** but I tried to unban them anyways.`; + return `${util.emojis.warn} **${user.tag}** is not banned but I tried to unban them anyways.`; case 'success': return `${util.emojis.success} Successfully unbanned **${user.tag}**.`; } diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts index 7d84b5e..48ba90d 100644 --- a/src/lib/extensions/discord-akairo/BushClient.ts +++ b/src/lib/extensions/discord-akairo/BushClient.ts @@ -1,4 +1,3 @@ -import chalk from 'chalk'; import { AkairoClient, ContextMenuCommandHandler } from 'discord-akairo'; import { Awaited, @@ -21,7 +20,6 @@ import eventsIntercept from 'events-intercept'; import JSON5 from 'json5'; import 'json5/lib/register'; import path from 'path'; -import { exit } from 'process'; import readline from 'readline'; import { Sequelize } from 'sequelize'; import { abbreviatedNumberTypeCaster } from '../../../arguments/abbreviatedNumber'; @@ -292,7 +290,8 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re dialect: 'postgres', host: this.config.db.host, port: this.config.db.port, - logging: this.config.logging.db ? (sql) => this.logger.debug(sql) : false + logging: this.config.logging.db ? (sql) => this.logger.debug(sql) : false, + timezone: 'America/New_York' }); } @@ -337,9 +336,9 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re inhibitors: this.inhibitorHandler, tasks: this.taskHandler }; - for (const loader of Object.keys(loaders)) { + for (const loader in loaders) { try { - loaders[loader as keyof typeof loaders].loadAll(); + await loaders[loader as keyof typeof loaders].loadAll(); void this.logger.success('startup', `Successfully loaded <<${loader}>>.`, false); } catch (e) { void this.logger.error('startup', `Unable to load loader <<${loader}>> with error:\n${e?.stack || e}`, false); @@ -367,9 +366,10 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re } catch (e) { await this.console.error( 'startup', - `Failed to connect to <<database>> with error:\n${typeof e}` === 'object' ? e?.stack : e, + `Failed to connect to <<database>> with error:\n${util.inspect(e, { colors: true, depth: 1 })}`, false ); + process.exit(2); } } @@ -397,8 +397,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re await this.#init(); await this.login(this.token!); } catch (e) { - await this.console.error('start', chalk.red(e?.stack || e), false); - exit(2); + await this.console.error('start', util.inspect(e, { colors: true, depth: 1 }), false); } } diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index 38e1a06..c15ca1c 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -925,11 +925,12 @@ export class BushClientUtil extends ClientUtil { #mapCredential(old: string): string { const mapping = { - ['token']: 'Main Token', - ['devToken']: 'Dev Token', - ['betaToken']: 'Beta Token', - ['hypixelApiKey']: 'Hypixel Api Key', - ['wolframAlphaAppId']: 'Wolfram|Alpha App ID' + token: 'Main Token', + devToken: 'Dev Token', + betaToken: 'Beta Token', + hypixelApiKey: 'Hypixel Api Key', + wolframAlphaAppId: 'Wolfram|Alpha App ID', + dbPassword: 'Database Password' }; return mapping[old as keyof typeof mapping] || old; } @@ -938,8 +939,10 @@ export class BushClientUtil extends ClientUtil { * Redacts credentials from a string */ public redact(text: string) { - for (const credentialName in client.config.credentials) { - const credential = client.config.credentials[credentialName as keyof typeof client.config.credentials]; + for (const credentialName in { ...client.config.credentials, dbPassword: client.config.db.password }) { + const credential = { ...client.config.credentials, dbPassword: client.config.db.password }[ + credentialName as keyof typeof client.config.credentials + ]; const replacement = this.#mapCredential(credentialName); const escapeRegex = /[.*+?^${}()|[\]\\]/g; text = text.replace(new RegExp(credential.toString().replace(escapeRegex, '\\$&'), 'g'), `[${replacement} Omitted]`); @@ -1182,14 +1185,18 @@ export class BushClientUtil extends ClientUtil { modlog: string; extraInfo?: Snowflake; }): Promise<ActivePunishment | null> { - const expires = options.duration ? new Date(new Date().getTime() + options.duration ?? 0) : undefined; + const expires = options.duration ? new Date(+new Date() + options.duration ?? 0) : undefined; const user = (await util.resolveNonCachedUser(options.user))!.id; const guild = client.guilds.resolveId(options.guild)!; const type = this.#findTypeEnum(options.type)!; - const entry = options.extraInfo - ? ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog, extraInfo: options.extraInfo }) - : ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog }); + console.debug(expires); + + const entry = ActivePunishment.build( + options.extraInfo + ? { user, type, guild, expires, modlog: options.modlog, extraInfo: options.extraInfo } + : { user, type, guild, expires, modlog: options.modlog } + ); return await entry.save().catch(async (e) => { await util.handleError('createPunishmentEntry', e); return null; @@ -1200,6 +1207,7 @@ export class BushClientUtil extends ClientUtil { type: 'mute' | 'ban' | 'role' | 'block'; user: BushGuildMemberResolvable; guild: BushGuildResolvable; + extraInfo?: Snowflake; }): Promise<boolean> { const user = await util.resolveNonCachedUser(options.user); const guild = client.guilds.resolveId(options.guild); @@ -1211,7 +1219,9 @@ export class BushClientUtil extends ClientUtil { const entries = await ActivePunishment.findAll({ // finding all cases of a certain type incase there were duplicates or something - where: { user: user.id, guild: guild, type } + where: options.extraInfo + ? { user: user.id, guild: guild, type, extraInfo: options.extraInfo } + : { user: user.id, guild: guild, type } }).catch(async (e) => { await util.handleError('removePunishmentEntry', e); success = false; @@ -1243,6 +1253,28 @@ export class BushClientUtil extends ClientUtil { else return humanizeDuration(duration, { language: 'en', maxDecimalPoints: 2 }); } + public timestampDuration(duration: number): string { + return `<t:${Math.round(duration / 1000)}:R>`; + } + + /** + * **Styles:** + * - **t**: Short Time + * - **T**: Long Time + * - **d**: Short Date + * - **D**: Long Date + * - **f**: Short Date/Time + * - **F**: Long Date/Time + * - **R**: Relative Time + */ + public timestamp<D extends Date | undefined | null>( + date: D, + style: 't' | 'T' | 'd' | 'D' | 'f' | 'F' | 'R' = 'f' + ): D extends Date ? string : undefined { + if (!date) return date as unknown as D extends Date ? string : undefined; + return `<t:${Math.round(date.getTime() / 1000)}:${style}>` as unknown as D extends Date ? string : undefined; + } + public dateDelta(date: Date, largest?: number) { return this.humanizeDuration(moment(date).diff(moment()), largest ?? 3); } diff --git a/src/lib/extensions/discord.js/BushClientEvents.d.ts b/src/lib/extensions/discord.js/BushClientEvents.d.ts index 96dc4c5..eb36153 100644 --- a/src/lib/extensions/discord.js/BushClientEvents.d.ts +++ b/src/lib/extensions/discord.js/BushClientEvents.d.ts @@ -85,7 +85,10 @@ export interface BushClientEvents extends ClientEvents { inviteDelete: [invite: Invite]; messageCreate: [message: BushMessage]; messageDelete: [message: BushMessage | PartialBushMessage]; - messageReactionRemoveAll: [message: BushMessage | PartialBushMessage]; + messageReactionRemoveAll: [ + message: BushMessage | PartialBushMessage, + reactions: Collection<string, BushMessageReaction> + ]; messageReactionRemoveEmoji: [ reaction: BushMessageReaction | PartialBushMessageReaction ]; diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts index b5bc407..8e855f7 100644 --- a/src/lib/extensions/discord.js/BushGuildMember.ts +++ b/src/lib/extensions/discord.js/BushGuildMember.ts @@ -199,7 +199,7 @@ export class BushGuildMember extends GuildMember { const ret = await (async () => { if (options.addToModlog) { const { log: modlog } = await util.createModLogEntry({ - type: ModLogType.PERM_PUNISHMENT_ROLE, + type: ModLogType.REMOVE_PUNISHMENT_ROLE, guild: this.guild, moderator: moderator.id, user: this, @@ -212,7 +212,8 @@ export class BushGuildMember extends GuildMember { const punishmentEntrySuccess = await util.removePunishmentEntry({ type: 'role', user: this, - guild: this.guild + guild: this.guild, + extraInfo: options.role.id }); if (!punishmentEntrySuccess) return 'error removing role entry'; diff --git a/src/lib/models/ActivePunishment.ts b/src/lib/models/ActivePunishment.ts index f453426..12b0cab 100644 --- a/src/lib/models/ActivePunishment.ts +++ b/src/lib/models/ActivePunishment.ts @@ -131,7 +131,7 @@ export class ActivePunishment } }, extraInfo: { - type: DataTypes.DATE, + type: DataTypes.STRING, allowNull: true }, expires: { diff --git a/src/lib/utils/BushLogger.ts b/src/lib/utils/BushLogger.ts index c2a9989..f00c19c 100644 --- a/src/lib/utils/BushLogger.ts +++ b/src/lib/utils/BushLogger.ts @@ -156,7 +156,7 @@ export class BushLogger { .setDescription(`**[${header}]** ${this.#parseFormatting(this.#stripColor(newContent), '', true)}`) .setColor(util.colors.warn) .setTimestamp(); - await this.channelLog({ embeds: [embed] }); + await this.channelError({ embeds: [embed] }); } /** diff --git a/src/listeners/message/autoThread.ts b/src/listeners/message/autoThread.ts index 04f6bcf..a254337 100644 --- a/src/listeners/message/autoThread.ts +++ b/src/listeners/message/autoThread.ts @@ -6,8 +6,8 @@ import { BushClientEvents } from '../../lib/extensions/discord.js/BushClientEven export default class autoThreadListener extends BushListener { public constructor() { super('autoThread', { - emitter: 'commandHandler', - event: 'messageInvalid', + emitter: 'client', + event: 'messageCreate', category: 'message' }); } @@ -23,6 +23,17 @@ export default class autoThreadListener extends BushListener { message.content.includes('<:yes:822211477624586260>') ) return; + + if ( + (message.content.trim().startsWith(await message.guild.getSetting('prefix')) || + message.content.trim().startsWith(`<@!${client.user!.id}>`) || + message.content.trim().startsWith(`<@${client.user!.id}>`)) && + client.commandHandler.aliases.some((alias) => message.content.includes(alias)) + ) + return; + + if (message.thread) return; + // todo: make these configurable etc... if (message.guild.id !== '516977525906341928') return; // mb if (message.channel.id !== '714332750156660756') return; // neu-support-1 diff --git a/src/listeners/other/promiseRejection.ts b/src/listeners/other/promiseRejection.ts index 130daa3..dc21c3f 100644 --- a/src/listeners/other/promiseRejection.ts +++ b/src/listeners/other/promiseRejection.ts @@ -10,8 +10,11 @@ export default class PromiseRejectionListener extends BushListener { } public override async exec(error: Error): Promise<void> { - // eslint-disable-next-line @typescript-eslint/no-base-to-string - void client.console.error('promiseRejection', `An unhanded promise rejection occurred:\n${error.stack ?? error}`, false); + void client.console.error( + 'promiseRejection', + `An unhanded promise rejection occurred:\n${typeof error == 'object' ? error.stack : error}`, + false + ); if (!error.message.includes('reason: getaddrinfo ENOTFOUND canary.discord.com')) void client.console.channelError({ embeds: [await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error })] diff --git a/src/listeners/other/uncaughtException.ts b/src/listeners/other/uncaughtException.ts index 47db37f..4ba47bd 100644 --- a/src/listeners/other/uncaughtException.ts +++ b/src/listeners/other/uncaughtException.ts @@ -10,8 +10,11 @@ export default class UncaughtExceptionListener extends BushListener { } public override async exec(error: Error): Promise<void> { - // eslint-disable-next-line @typescript-eslint/no-base-to-string - void client.console.error('uncaughtException', `An uncaught exception occurred:\n${error?.stack ?? error}`, false); + void client.console.error( + 'uncaughtException', + `An uncaught exception occurred:\n${typeof error == 'object' ? error.stack : error}`, + false + ); void client.console.channelError({ embeds: [await CommandErrorListener.generateErrorEmbed({ type: 'uncaughtException', error: error })] }); diff --git a/src/listeners/other/warning.ts b/src/listeners/other/warning.ts new file mode 100644 index 0000000..d85e9e3 --- /dev/null +++ b/src/listeners/other/warning.ts @@ -0,0 +1,22 @@ +import { BushListener } from '@lib'; +import CommandErrorListener from '../commands/commandError'; + +export default class WarningListener extends BushListener { + public constructor() { + super('warning', { + emitter: 'process', + event: 'warning' + }); + } + + public override async exec(error: Error): Promise<void> { + void client.console.warn('warning', `A warning occurred:\n${typeof error == 'object' ? error.stack : error}`, false); + void client.console.channelError({ + embeds: [ + (await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error })) + .setColor(util.colors.warn) + .setTitle('A Warning Occurred') + ] + }); + } +} |