From 31d3e2b1d7873b33c678e14131b3d46f8a830650 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Fri, 8 May 2020 18:29:17 +0300 Subject: [PATCH] Another potential fix for Node.js 13/14 incompatibility --- backend/src/index.ts | 7 ++----- backend/src/plugins/AutoReactionsPlugin.ts | 7 +++---- backend/src/plugins/Cases.ts | 6 ++---- backend/src/plugins/Logs.ts | 4 ++-- backend/src/plugins/ModActions.ts | 10 +++++----- backend/src/plugins/ReactionRoles.ts | 5 ++--- backend/src/plugins/Slowmode.ts | 4 ++-- backend/src/plugins/ZeppelinPlugin.ts | 4 ++-- backend/src/utils.ts | 17 +++++++++++++---- 9 files changed, 33 insertions(+), 31 deletions(-) diff --git a/backend/src/index.ts b/backend/src/index.ts index bc288d01..45bba7f7 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -7,9 +7,6 @@ const fsp = fs.promises; import { Knub, logger, PluginError, Plugin, IGlobalConfig, IGuildConfig } from "knub"; import { SimpleError } from "./SimpleError"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line -import DiscordHTTPError = require("eris/lib/errors/DiscordHTTPError.js"); // tslint:disable-line - import { Configs } from "./data/Configs"; require("dotenv").config({ path: path.resolve(process.cwd(), "bot.env") }); @@ -48,7 +45,7 @@ if (process.env.NODE_ENV === "production") { console.error(`Exiting after ${RECENT_PLUGIN_ERROR_EXIT_THRESHOLD} plugin errors`); process.exit(1); } - } else if (err instanceof DiscordRESTError || err instanceof DiscordHTTPError) { + } else if (isDiscordRESTError(err) || isDiscordHTTPError(err)) { // Discord API errors, usually safe to just log instead of crash // We still bail if we get a ton of them in a short amount of time if (++recentDiscordErrors >= RECENT_DISCORD_ERROR_EXIT_THRESHOLD) { @@ -85,7 +82,7 @@ import { connect } from "./data/db"; import { availablePlugins, availableGlobalPlugins, basePlugins } from "./plugins/availablePlugins"; import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { customArgumentTypes } from "./customArgumentTypes"; -import { errorMessage, successMessage } from "./utils"; +import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils"; import { startUptimeCounter } from "./uptime"; import { AllowedGuilds } from "./data/AllowedGuilds"; import { IZeppelinGuildConfig, IZeppelinGlobalConfig } from "./types"; diff --git a/backend/src/plugins/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactionsPlugin.ts index ba34adee..231a7cbc 100644 --- a/backend/src/plugins/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactionsPlugin.ts @@ -3,9 +3,8 @@ import { GuildSavedMessages } from "../data/GuildSavedMessages"; import { SavedMessage } from "../data/entities/SavedMessage"; import { GuildAutoReactions } from "../data/GuildAutoReactions"; import { Message } from "eris"; -import { customEmojiRegex, errorMessage, isEmoji } from "../utils"; +import { customEmojiRegex, errorMessage, isDiscordRESTError, isEmoji } from "../utils"; import { CommandInfo, trimPluginDescription, ZeppelinPlugin } from "./ZeppelinPlugin"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import * as t from "io-ts"; import { GuildLogs } from "../data/GuildLogs"; import { LogType } from "../data/LogType"; @@ -128,7 +127,7 @@ export class AutoReactionsPlugin extends ZeppelinPlugin { try { realMsg = await this.bot.getMessage(msg.channel_id, msg.id); } catch (e) { - if (e instanceof DiscordRESTError) { + if (isDiscordRESTError(e)) { logger.warn( `Could not load auto-reaction message ${msg.channel_id}/${msg.id} in guild ${this.guild.name} (${this.guildId}) (error code ${e.code})`, ); @@ -157,7 +156,7 @@ export class AutoReactionsPlugin extends ZeppelinPlugin { try { await realMsg.addReaction(reaction); } catch (e) { - if (e instanceof DiscordRESTError) { + if (isDiscordRESTError(e)) { logger.warn( `Could not apply auto-reaction to ${msg.channel_id}/${msg.id} in guild ${this.guild.name} (${this.guildId}) (error code ${e.code})`, ); diff --git a/backend/src/plugins/Cases.ts b/backend/src/plugins/Cases.ts index d2a33598..98e30c7c 100644 --- a/backend/src/plugins/Cases.ts +++ b/backend/src/plugins/Cases.ts @@ -10,11 +10,9 @@ import { IPluginOptions, logger } from "knub"; import { GuildLogs } from "../data/GuildLogs"; import { LogType } from "../data/LogType"; import * as t from "io-ts"; -import { tNullable } from "../utils"; +import { isDiscordRESTError, tNullable } from "../utils"; import { ERRORS } from "../RecoverablePluginError"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line - const ConfigSchema = t.type({ log_automatic_actions: t.boolean, case_log_channel: tNullable(t.string), @@ -277,7 +275,7 @@ export class CasesPlugin extends ZeppelinPlugin { try { result = await caseLogChannel.createMessage(content, file); } catch (e) { - if (e instanceof DiscordRESTError && e.code === 50013) { + if (isDiscordRESTError(e) && e.code === 50013) { logger.warn( `Missing permissions to post mod cases in <#${caseLogChannel.id}> in guild ${this.guild.name} (${this.guild.id})`, ); diff --git a/backend/src/plugins/Logs.ts b/backend/src/plugins/Logs.ts index 086b8fe2..399426f3 100644 --- a/backend/src/plugins/Logs.ts +++ b/backend/src/plugins/Logs.ts @@ -2,10 +2,10 @@ import { decorators as d, IPluginOptions, logger } from "knub"; import { GuildLogs } from "../data/GuildLogs"; import { LogType } from "../data/LogType"; import { Attachment, Channel, Constants as ErisConstants, Embed, Member, TextChannel, User } from "eris"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import { createChunkedMessage, findRelevantAuditLogEntry, + isDiscordRESTError, messageSummary, noop, stripObjectToScalars, @@ -263,7 +263,7 @@ export class LogsPlugin extends ZeppelinPlugin { try { return await findRelevantAuditLogEntry(this.guild, actionType, userId, attempts, attemptDelay); } catch (e) { - if (e instanceof DiscordRESTError && e.code === 50013) { + if (isDiscordRESTError(e) && e.code === 50013) { this.guildLogs.log(LogType.BOT_ALERT, { body: "Missing permissions to read audit log", }); diff --git a/backend/src/plugins/ModActions.ts b/backend/src/plugins/ModActions.ts index 6086ad7c..a7e23e09 100644 --- a/backend/src/plugins/ModActions.ts +++ b/backend/src/plugins/ModActions.ts @@ -1,7 +1,5 @@ import { decorators as d, IPluginOptions, logger, waitForReaction, waitForReply } from "knub"; import { Attachment, Constants as ErisConstants, Guild, Member, Message, TextChannel, User } from "eris"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line -import DiscordHTTPError = require("eris/lib/errors/DiscordHTTPError.js"); // tslint:disable-line import humanizeDuration from "humanize-duration"; import { GuildCases } from "../data/GuildCases"; import { @@ -10,6 +8,8 @@ import { disableUserNotificationStrings, errorMessage, findRelevantAuditLogEntry, + isDiscordHTTPError, + isDiscordRESTError, MINUTES, multiSorter, notifyUser, @@ -281,7 +281,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { const bans = (await this.guild.getBans()) as any; return bans.some(b => b.user.id === userId); } catch (e) { - if (e instanceof DiscordHTTPError && e.code === 500) { + if (isDiscordHTTPError(e) && e.code === 500) { return false; } @@ -293,7 +293,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { try { return await findRelevantAuditLogEntry(this.guild, actionType, userId, attempts, attemptDelay); } catch (e) { - if (e instanceof DiscordRESTError && e.code === 50013) { + if (isDiscordRESTError(e) && e.code === 50013) { this.serverLogs.log(LogType.BOT_ALERT, { body: "Missing permissions to read audit log", }); @@ -827,7 +827,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { this.sendErrorMessage(msg.channel, "Could not mute the user: no mute role set in config"); - } else if (e instanceof DiscordRESTError && e.code === 10007) { + } else if (isDiscordRESTError(e) && e.code === 10007) { this.sendErrorMessage(msg.channel, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); diff --git a/backend/src/plugins/ReactionRoles.ts b/backend/src/plugins/ReactionRoles.ts index 5e75eadf..4f48ca9a 100644 --- a/backend/src/plugins/ReactionRoles.ts +++ b/backend/src/plugins/ReactionRoles.ts @@ -1,12 +1,11 @@ import { decorators as d, IPluginOptions, logger } from "knub"; -import { CustomEmoji, errorMessage, isSnowflake, noop, sleep } from "../utils"; +import { CustomEmoji, errorMessage, isDiscordRESTError, isSnowflake, noop, sleep } from "../utils"; import { GuildReactionRoles } from "../data/GuildReactionRoles"; import { Message, TextChannel } from "eris"; import { ZeppelinPlugin } from "./ZeppelinPlugin"; import { GuildSavedMessages } from "../data/GuildSavedMessages"; import { Queue } from "../Queue"; import { ReactionRole } from "../data/entities/ReactionRole"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import * as t from "io-ts"; import { ERRORS, RecoverablePluginError } from "../RecoverablePluginError"; import Timeout = NodeJS.Timeout; @@ -143,7 +142,7 @@ export class ReactionRolesPlugin extends ZeppelinPlugin { try { targetMessage = await channel.getMessage(messageId); } catch (e) { - if (e instanceof DiscordRESTError) { + if (isDiscordRESTError(e)) { if (e.code === 10008) { // Unknown message, remove reaction roles from the message logger.warn( diff --git a/backend/src/plugins/Slowmode.ts b/backend/src/plugins/Slowmode.ts index 63200761..27804049 100644 --- a/backend/src/plugins/Slowmode.ts +++ b/backend/src/plugins/Slowmode.ts @@ -4,6 +4,7 @@ import { convertDelayStringToMS, createChunkedMessage, errorMessage, + isDiscordRESTError, noop, stripObjectToScalars, successMessage, @@ -14,7 +15,6 @@ import humanizeDuration from "humanize-duration"; import { ZeppelinPlugin } from "./ZeppelinPlugin"; import { SavedMessage } from "../data/entities/SavedMessage"; import { GuildSavedMessages } from "../data/GuildSavedMessages"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import { GuildLogs } from "../data/GuildLogs"; import { LogType } from "../data/LogType"; import * as t from "io-ts"; @@ -99,7 +99,7 @@ export class SlowmodePlugin extends ZeppelinPlugin { } catch (e) { const user = this.bot.users.get(userId) || new UnknownUser({ id: userId }); - if (e instanceof DiscordRESTError && e.code === 50013) { + if (isDiscordRESTError(e) && e.code === 50013) { logger.warn( `Missing permissions to apply bot slowmode to user ${userId} on channel ${channel.name} (${channel.id}) on server ${this.guild.name} (${this.guildId})`, ); diff --git a/backend/src/plugins/ZeppelinPlugin.ts b/backend/src/plugins/ZeppelinPlugin.ts index ef01ff9a..e2e46e9b 100644 --- a/backend/src/plugins/ZeppelinPlugin.ts +++ b/backend/src/plugins/ZeppelinPlugin.ts @@ -2,6 +2,7 @@ import { configUtils, IBasePluginConfig, IPluginOptions, logger, Plugin } from " import * as t from "io-ts"; import { deepKeyIntersect, + isDiscordRESTError, isSnowflake, isUnicodeEmoji, MINUTES, @@ -16,7 +17,6 @@ import { UnknownUser, } from "../utils"; import { Invite, Member, User } from "eris"; -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import { performance } from "perf_hooks"; import { decodeAndValidateStrict, StrictValidationError, validate } from "../validatorUtils"; import { SimpleCache } from "../SimpleCache"; @@ -270,7 +270,7 @@ export class ZeppelinPlugin< try { member = userId && (await this.bot.getRESTGuildMember(this.guild.id, userId)); } catch (e) { - if (!(e instanceof DiscordRESTError)) { + if (!isDiscordRESTError(e)) { throw e; } } diff --git a/backend/src/utils.ts b/backend/src/utils.ts index fa147458..0bdc0742 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -15,8 +15,6 @@ import { TextChannel, User, } from "eris"; -import DiscordHTTPError = require("eris/lib/errors/DiscordHTTPError.js"); // tslint:disable-line -import DiscordRESTError = require("eris/lib/errors/DiscordRESTError.js"); // tslint:disable-line import url from "url"; import tlds from "tlds"; import emojiRegex from "emoji-regex"; @@ -52,6 +50,17 @@ export const WEEKS = 7 * 24 * HOURS; export const EMPTY_CHAR = "\u200b"; +export const DISCORD_HTTP_ERROR_NAME = "DiscordHTTPError"; +export const DISCORD_REST_ERROR_NAME = "DiscordRESTError"; + +export function isDiscordHTTPError(err: Error | string) { + return typeof err === "object" && err.constructor?.name === DISCORD_HTTP_ERROR_NAME; +} + +export function isDiscordRESTError(err: Error | string) { + return typeof err === "object" && err.constructor?.name === DISCORD_REST_ERROR_NAME; +} + export function tNullable>(type: T) { return t.union([type, t.undefined, t.null], `Nullable<${type.name}>`); } @@ -352,13 +361,13 @@ export async function findRelevantAuditLogEntry( auditLogs = await guild.getAuditLogs(5, null, actionType); } catch (e) { // If we don't have permission to read audit log, set audit log requests on cooldown - if (e instanceof DiscordRESTError && e.code === 50013) { + if (isDiscordRESTError(e) && e.code === 50013) { auditLogNextAttemptAfterFail.set(guild.id, Date.now() + AUDIT_LOG_FAIL_COOLDOWN); throw e; } // Ignore internal server errors which seem to be pretty common with audit log requests - if (!(e instanceof DiscordHTTPError) || e.code !== 500) { + if (!isDiscordHTTPError(e) || e.code !== 500) { throw e; } }