diff --git a/src/Util.ts b/src/Util.ts index 62b90d0..3d62254 100644 --- a/src/Util.ts +++ b/src/Util.ts @@ -1,6 +1,7 @@ import { promisify } from 'util'; import childProcess from 'child_process'; import nodemailer from 'nodemailer'; +import { Message } from 'eris'; import Client from './Client'; import Command from './class/Command'; @@ -39,4 +40,11 @@ export default class Util { } return undefined; } + + public async handleError(error: Error, message?: Message, command?: Command): Promise { + const stack = await this.client.createMessage('595788220764127272', `\`\`\`js\n${error.stack}\n\`\`\``); + if (command) this.client.commands.get(command.name).enabled = false; + if (message) message.channel.createMessage(`***${this.client.stores.emojis.error} An unexpected error has occured - please contact a member of the Engineering Team.${command ? ' This command has been disabled.' : ''}***`); + return stack; + } } diff --git a/src/commands/lock.ts b/src/commands/lock.ts index bc0d47f..051118a 100644 --- a/src/commands/lock.ts +++ b/src/commands/lock.ts @@ -2,8 +2,11 @@ import fs from 'fs-extra'; import { Message } from 'eris'; import Client from '../Client'; import Command from '../class/Command'; +import Util from '../Util'; export default class Lock extends Command { + util: Util = new Util(this.client) + constructor(client: Client) { super(client); this.name = 'lock'; @@ -13,9 +16,12 @@ export default class Lock extends Command { } public async run(message: Message, args: string[]) { // eslint-disable-line - let account = await this.client.db.Account.findOne({ account: args[0] }); - if (!account) account = await this.client.db.Account.findOne({ userID: args[0].replace(/[<@!>]/gi, '') }); - if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot find user.***`); - const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locking account...***`); + try { + const account = await this.client.db.Account.findOne({ $or: [{ account: args[0] }, { userID: args[0].replace(/[<@!>]/gi, '') }] }); + if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot find user.***`); + const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locking account...***`); + } catch (error) { + return this.util.handleError(error, message, this); + } } } diff --git a/src/commands/modlogs.ts b/src/commands/modlogs.ts index 851dcc7..af96f6f 100644 --- a/src/commands/modlogs.ts +++ b/src/commands/modlogs.ts @@ -3,8 +3,11 @@ import { createPaginationEmbed } from 'eris-pagination'; import Client from '../Client'; import Command from '../class/Command'; import RichEmbed from '../class/RichEmbed'; +import Util from '../Util'; export default class Modlogs extends Command { + util: Util = new Util(this.client) + constructor(client: Client) { super(client); this.name = 'modlogs'; @@ -15,38 +18,42 @@ export default class Modlogs extends Command { } public async run(message: Message, args: string[]) { - const msg: Message = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locating modlogs...***`); - const query = await this.client.db.Moderation.find({ $or: [{ account: args.join(' ') }, { userID: args.filter((a) => a)[0].replace(/[<@!>]/g, '') }] }); - if (!query.length) return msg.edit(`***${this.client.stores.emojis.error} Cannot locate modlogs for ${args.join(' ')}***`); + try { + const msg: Message = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locating modlogs...***`); + const query = await this.client.db.Moderation.find({ $or: [{ account: args.join(' ') }, { userID: args.filter((a) => a)[0].replace(/[<@!>]/g, '') }] }); + if (!query.length) return msg.edit(`***${this.client.stores.emojis.error} Cannot locate modlogs for ${args.join(' ')}***`); - let index = 0; const logs: {name: string, value: string, inline: boolean}[][] = [[]]; - const formatted = query.map((log) => { - const { account, moderatorID, reason, type, date } = log; - const name = type; - const value = `**Account name:** ${account}\n**Moderator:** <@${moderatorID}>\n**Reason:** ${reason}\n**Date:** ${date.toLocaleString('en-us')} EST`; - const inline = true; - return { name, value, inline }; - }); - const users = [...new Set(query.map((log) => log.userID))].map((u) => `<@${u}>`); + let index = 0; const logs: {name: string, value: string, inline: boolean}[][] = [[]]; + const formatted = query.map((log) => { + const { account, moderatorID, reason, type, date } = log; + const name = type; + const value = `**Account name:** ${account}\n**Moderator:** <@${moderatorID}>\n**Reason:** ${reason}\n**Date:** ${date.toLocaleString('en-us')} EST`; + const inline = true; + return { name, value, inline }; + }); + const users = [...new Set(query.map((log) => log.userID))].map((u) => `<@${u}>`); - while (query.length) { - if (logs[index].length >= 25) { index += 1; logs[index] = []; } - logs[index].push(formatted[0]); formatted.shift(); + while (query.length) { + if (logs[index].length >= 25) { index += 1; logs[index] = []; } + logs[index].push(formatted[0]); formatted.shift(); + } + + const embeds = logs.map((l) => { + const embed = new RichEmbed(); + embed.setDescription(`List of Cloud moderation logs for ${users.join(', ')}`); + embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL, 'https://libraryofcode.us'); + embed.setTitle('Cloud Modlogs/Infractions'); + embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL); + l.forEach((f) => embed.addField(f.name, f.value, f.inline)); + embed.setTimestamp(); + embed.setColor(3447003); + return embed; + }); + + createPaginationEmbed(message, this.client, embeds, {}, msg); + return msg; + } catch (error) { + return this.util.handleError(error, message, this); } - - const embeds = logs.map((l) => { - const embed = new RichEmbed(); - embed.setDescription(`List of Cloud moderation logs for ${users.join(', ')}`); - embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL, 'https://libraryofcode.us'); - embed.setTitle('Cloud Modlogs/Infractions'); - embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL); - l.forEach((f) => embed.addField(f.name, f.value, f.inline)); - embed.setTimestamp(); - embed.setColor(3447003); - return embed; - }); - - createPaginationEmbed(message, this.client, embeds, {}, msg); - return msg; } } diff --git a/src/commands/ping.ts b/src/commands/ping.ts index 692041f..c6c1681 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -1,8 +1,11 @@ import { Message } from 'eris'; import Client from '../Client'; import Command from '../class/Command'; +import Util from '../Util'; export default class Ping extends Command { + util: Util = new Util(this.client) + constructor(client: Client) { super(client); this.name = 'ping'; @@ -11,8 +14,12 @@ export default class Ping extends Command { } public async run(message: Message) { - const clientStart: number = Date.now(); - const msg: Message = await message.channel.createMessage('🏓 Pong!'); - msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``); + try { + const clientStart: number = Date.now(); + const msg: Message = await message.channel.createMessage('🏓 Pong!'); + msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``); + } catch (error) { + this.util.handleError(error, message, this); + } } } diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index fd06dee..7bad7a5 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -14,21 +14,25 @@ export default class { util: Util = new Util(this.client) async run(message: Message) { - const noPrefix: string[] = message.content.slice(prefix.length).trim().split(/ +/g); - const command: string = noPrefix[0].toLowerCase(); - const resolved: Command = this.util.resolveCommand(command); - if (!resolved) return; - if (resolved.guildOnly && !(message.channel instanceof TextChannel)) return; - const hasUserPerms: boolean = resolved.permissions.users.includes(message.author.id); - let hasRolePerms: boolean = false; - for (const role of resolved.permissions.roles) { - if (message.member && message.member.roles.includes(role)) { - hasRolePerms = true; break; + try { + const noPrefix: string[] = message.content.slice(prefix.length).trim().split(/ +/g); + const command: string = noPrefix[0].toLowerCase(); + const resolved: Command = this.util.resolveCommand(command); + if (!resolved) return; + if (resolved.guildOnly && !(message.channel instanceof TextChannel)) return; + const hasUserPerms: boolean = resolved.permissions.users.includes(message.author.id); + let hasRolePerms: boolean = false; + for (const role of resolved.permissions.roles) { + if (message.member && message.member.roles.includes(role)) { + hasRolePerms = true; break; + } } + if (!hasRolePerms && !hasUserPerms) return; + if (!resolved.enabled) { message.channel.createMessage(`***${this.client.stores.emojis.error} This command has been disabled***`); return; } + const args: string[] = noPrefix.slice(1); + resolved.run(message, args); + } catch (error) { + this.util.handleError(error, message); } - if (!hasRolePerms && !hasUserPerms) return; - if (!resolved.enabled) { message.channel.createMessage(`***${this.client.stores.emojis.error} This command has been disabled***`); return; } - const args: string[] = noPrefix.slice(1); - resolved.run(message, args); } }