Skip to content

Commit

Permalink
refactor: add new function to handle errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dev-737 committed Jan 6, 2024
1 parent 55e5cb3 commit ec37481
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 79 deletions.
7 changes: 3 additions & 4 deletions src/commands/context-menu/blacklist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { colors, emojis } from '../../utils/Constants.js';
import { CustomID } from '../../utils/CustomID.js';
import { RegisterInteractionHandler } from '../../decorators/Interaction.js';
import { simpleEmbed } from '../../utils/Utils.js';
import { time } from 'discord.js';

export default class Blacklist extends BaseCommand {
data: RESTPostAPIApplicationCommandsJSONBody = {
Expand Down Expand Up @@ -173,7 +174,7 @@ export default class Blacklist extends BaseCommand {
},
{
name: 'Expires',
value: expires ? `<t:${Math.round(expires.getTime() / 1000)}:R>` : 'Never.',
value: expires ? `${time(Math.round(expires.getTime() / 1000), 'R')}` : 'Never.',
inline: true,
},
);
Expand Down Expand Up @@ -255,9 +256,7 @@ export default class Blacklist extends BaseCommand {

if (server) {
const hubLogger = await new HubLogsManager(originalMsg.hubId).init();
await hubLogger
.logBlacklist(server, interaction.user, reason, expires)
.catch(() => null);
await hubLogger.logBlacklist(server, interaction.user, reason, expires).catch(() => null);
}

await interaction.editReply({ embeds: [successEmbed], components: [] });
Expand Down
11 changes: 2 additions & 9 deletions src/commands/slash/Main/blacklist/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import {
Collection,
RESTPostAPIApplicationCommandsJSONBody,
} from 'discord.js';
import { handleError } from '../../../../utils/Utils.js';
import BaseCommand from '../../../BaseCommand.js';
import db from '../../../../utils/Db.js';
import Logger from '../../../../utils/Logger.js';
import { captureException } from '@sentry/node';
import { replyWithError } from '../../../../utils/Utils.js';

export default class BlacklistCommand extends BaseCommand {
// TODO: Put this in readme
Expand Down Expand Up @@ -171,12 +169,7 @@ export default class BlacklistCommand extends BaseCommand {
const subCommandName = interaction.options.getSubcommand();
const subcommand = BlacklistCommand.subcommands.get(subCommandName);

return await subcommand?.execute(interaction).catch((e) => {
Logger.error(e);
captureException(e);
// reply with an error message to the user
replyWithError(interaction, e.message);
});
return await subcommand?.execute(interaction).catch((e) => handleError(e, interaction));
}

async autocomplete(interaction: AutocompleteInteraction) {
Expand Down
9 changes: 4 additions & 5 deletions src/commands/slash/Main/blacklist/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { paginate } from '../../../../utils/Pagination.js';
import { colors } from '../../../../utils/Constants.js';
import { simpleEmbed } from '../../../../utils/Utils.js';
import { t } from '../../../../utils/Locale.js';
import { time } from 'discord.js';

export default class ListBlacklists extends BlacklistCommand {
async execute(interaction: ChatInputCommandInteraction) {
Expand All @@ -24,9 +25,7 @@ export default class ListBlacklists extends BlacklistCommand {

if (!hubInDb) {
await interaction.editReply({
embeds: [
simpleEmbed(t({ phrase: 'hub.notFound_mod', locale: interaction.user.locale })),
],
embeds: [simpleEmbed(t({ phrase: 'hub.notFound_mod', locale: interaction.user.locale }))],
});
return;
}
Expand Down Expand Up @@ -66,7 +65,7 @@ export default class ListBlacklists extends BlacklistCommand {
reason: `${hubData?.reason}`,
expires: !hubData?.expires
? 'Never.'
: `<t:${Math.round(hubData.expires.getTime() / 1000)}:R>`,
: `${time(Math.round(hubData.expires.getTime() / 1000), 'R')}`,
},
),
});
Expand Down Expand Up @@ -110,7 +109,7 @@ export default class ListBlacklists extends BlacklistCommand {
reason: `${hubData?.reason}`,
expires: !hubData?.expires
? 'Never.'
: `<t:${Math.round(hubData.expires.getTime() / 1000)}:R>`,
: `${time(Math.round(hubData.expires.getTime() / 1000), 'R')}`,
},
),
});
Expand Down
4 changes: 2 additions & 2 deletions src/commands/slash/Main/blacklist/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { captureException } from '@sentry/node';
import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import { ChatInputCommandInteraction, EmbedBuilder, time } from 'discord.js';
import { simpleEmbed } from '../../../../utils/Utils.js';
import { emojis } from '../../../../utils/Constants.js';
import db from '../../../../utils/Db.js';
Expand Down Expand Up @@ -111,7 +111,7 @@ export default class UserBlacklist extends BlacklistCommand {
},
{
name: 'Expires',
value: expires ? `<t:${Math.round(expires.getTime() / 1000)}:R>` : 'Never.',
value: expires ? `${time(Math.round(expires.getTime() / 1000), 'R')}` : 'Never.',
inline: true,
},
);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/slash/Main/blacklist/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChatInputCommandInteraction, EmbedBuilder } from 'discord.js';
import { ChatInputCommandInteraction, EmbedBuilder, time } from 'discord.js';
import db from '../../../../utils/Db.js';
import BlacklistCommand from './index.js';
import BlacklistManager from '../../../../managers/BlacklistManager.js';
Expand Down Expand Up @@ -100,7 +100,7 @@ export default class Server extends BlacklistCommand {
},
{
name: 'Expires',
value: expires ? `<t:${Math.round(expires.getTime() / 1000)}:R>` : 'Never.',
value: expires ? `${time(Math.round(expires.getTime() / 1000), 'R')}` : 'Never.',
inline: true,
},
);
Expand Down
11 changes: 8 additions & 3 deletions src/commands/slash/Main/hub/browse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TextInputStyle,
ModalSubmitInteraction,
ChannelSelectMenuInteraction,
time,
} from 'discord.js';
import db from '../../../../utils/Db.js';
import Hub from './index.js';
Expand Down Expand Up @@ -401,7 +402,10 @@ export default class Browse extends Hub {

// log the server join to hub
const hubLogger = await new HubLogsManager(hubDetails.id).init();
await hubLogger.logServerJoin(interaction.guild, { totalConnections, hubName: hubDetails.name });
await hubLogger.logServerJoin(interaction.guild, {
totalConnections,
hubName: hubDetails.name,
});
}
}

Expand Down Expand Up @@ -456,8 +460,9 @@ export default class Browse extends Hub {

const lastMessageTimestamp = lastMessage?.getTime() ?? 0;
const lastMessageStr = lastMessageTimestamp
? `<t:${Math.round(lastMessageTimestamp / 1000)}:R>`
? `${time(Math.round(lastMessageTimestamp / 1000), 'R')}`
: '-';
const hubCreatedAt = time(Math.round(hub.createdAt.getTime() / 1000), 'd');

return new EmbedBuilder()
.setTitle(hub.name)
Expand All @@ -467,7 +472,7 @@ export default class Browse extends Hub {
name: 'Information',
value: stripIndents`
${emojis.connect_icon} **Servers:** ${connections ?? 'Unknown.'}
${emojis.clock_icon} **Created At:** <t:${Math.round(hub.createdAt.getTime() / 1000)}:d>
${emojis.clock_icon} **Created At:** ${hubCreatedAt}
${emojis.chat_icon} **Last Message:** ${lastMessageStr}
`,
inline: true,
Expand Down
11 changes: 2 additions & 9 deletions src/commands/slash/Main/hub/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import {
} from 'discord.js';
import BaseCommand from '../../../BaseCommand.js';
import db from '../../../../utils/Db.js';
import { replyWithError } from '../../../../utils/Utils.js';
import Logger from '../../../../utils/Logger.js';
import { captureException } from '@sentry/node';
import { handleError } from '../../../../utils/Utils.js';

const hubOption: APIApplicationCommandBasicOption = {
type: ApplicationCommandOptionType.String,
Expand Down Expand Up @@ -284,12 +282,7 @@ export default class Hub extends BaseCommand {
interaction.options.getSubcommandGroup() || interaction.options.getSubcommand(),
);

return await subcommand?.execute(interaction).catch((e) => {
Logger.error(e);
captureException(e);

replyWithError(interaction, e.message);
});
return await subcommand?.execute(interaction).catch((e) => handleError(e, interaction));
}

async autocomplete(interaction: AutocompleteInteraction): Promise<unknown> {
Expand Down
11 changes: 2 additions & 9 deletions src/commands/slash/Staff/find/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import {
RESTPostAPIApplicationCommandsJSONBody,
} from 'discord.js';
import BaseCommand from '../../../BaseCommand.js';
import Logger from '../../../../utils/Logger.js';
import { captureException } from '@sentry/node';
import { replyWithError } from '../../../../utils/Utils.js';
import { handleError } from '../../../../utils/Utils.js';

export default class Find extends BaseCommand {
staffOnly = true;
Expand Down Expand Up @@ -64,12 +62,7 @@ export default class Find extends BaseCommand {
async execute(interaction: ChatInputCommandInteraction) {
const subcommand = Find.subcommands?.get(interaction.options.getSubcommand());

return await subcommand?.execute(interaction).catch((e) => {
Logger.error(e);
captureException(e);
// reply with an error message to the user
replyWithError(interaction, e.message);
});
return await subcommand?.execute(interaction).catch((e) => handleError(e, interaction));
}
async autocomplete(interaction: AutocompleteInteraction) {
const subcommand = interaction.options.getSubcommand();
Expand Down
11 changes: 2 additions & 9 deletions src/commands/slash/Support/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import {
Collection,
RESTPostAPIApplicationCommandsJSONBody,
} from 'discord.js';
import { handleError } from '../../../../utils/Utils.js';
import BaseCommand from '../../../BaseCommand.js';
import Logger from '../../../../utils/Logger.js';
import { captureException } from '@sentry/node';
import { replyWithError } from '../../../../utils/Utils.js';

export default class Support extends BaseCommand {
readonly data: RESTPostAPIApplicationCommandsJSONBody = {
Expand Down Expand Up @@ -50,11 +48,6 @@ export default class Support extends BaseCommand {
const subCommandName = interaction.options.getSubcommand();
const subcommand = Support.subcommands?.get(subCommandName);

await subcommand?.execute(interaction).catch((e) => {
Logger.error(e);
captureException(e);
// reply with an error message to the user
replyWithError(interaction, e.message);
});
await subcommand?.execute(interaction).catch((e) => handleError(e, interaction));
}
}
27 changes: 5 additions & 22 deletions src/managers/CommandManager.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { t } from '../utils/Locale.js';
import { join, dirname } from 'path';
import { CustomID } from '../utils/CustomID.js';
import { Interaction } from 'discord.js';
import { captureException } from '@sentry/node';
import { simpleEmbed, replyWithError } from '../utils/Utils.js';
import { Interaction, time } from 'discord.js';
import { simpleEmbed, handleError } from '../utils/Utils.js';
import { access, constants, readdirSync, statSync } from 'fs';
import Logger from '../utils/Logger.js';
import Factory from '../Factory.js';
import BaseCommand, { commandsMap } from '../commands/BaseCommand.js';

Expand Down Expand Up @@ -77,15 +75,15 @@ export default class CommandManager extends Factory {
await interaction.reply({
content: t(
{ phrase: 'errors.cooldown', locale: interaction.user.locale },
{ time: `until <t:${waitUntil}:T> (<t:${waitUntil}:R>)` },
{ time: `until ${time(waitUntil, 'T')} (${time(waitUntil, 'R')})` },
),
ephemeral: true,
});
return;
}

// run the command
command?.execute(interaction);
await command?.execute(interaction);
}
else {
const customId = CustomID.parseCustomId(interaction.customId);
Expand Down Expand Up @@ -114,22 +112,7 @@ export default class CommandManager extends Factory {
}
}
catch (e) {
// log the error to the system
Logger.error(e);
// capture the error to Sentry.io with additional information
captureException(e, {
user: { id: interaction.user.id, username: interaction.user.username },
extra: {
type: interaction.type,
identifier:
interaction.isCommand() || interaction.isAutocomplete()
? interaction.commandName
: CustomID.parseCustomId(interaction.customId),
},
});

// reply with an error message to the user
if (interaction.isRepliable()) replyWithError(interaction, e);
handleError(e, interaction);
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/updater/ReactionUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
StringSelectMenuBuilder,
User,
WebhookClient,
time,
} from 'discord.js';
import { sortReactions } from '../utils/Utils.js';
import { HubSettingsBitField } from '../utils/BitFields.js';
Expand Down Expand Up @@ -211,10 +212,9 @@ export default class ReactionUpdater extends Factory {
}

if (cooldown && cooldown > Date.now()) {
const timeString = time(Math.round(cooldown / 1000), 'R');
return await interaction.followUp({
content: `A little quick there! You can react again <t:${Math.round(
cooldown / 1000,
)}:R>!`,
content: `A little quick there! You can react again ${timeString}!`,
ephemeral: true,
});
}
Expand Down Expand Up @@ -317,8 +317,7 @@ export default class ReactionUpdater extends Factory {
})
.catch(() => null);


// FIXME: Fix not being able to react to messages with no reply button
// FIXME: Fix not being able to react to messages with reply button
const components = message?.components?.filter((row) => {
// filter all buttons that are not reaction buttons
row.components = row.components.filter((component) => {
Expand Down
29 changes: 29 additions & 0 deletions src/utils/Utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import db from './Db.js';
import Logger from './Logger.js';
import toLower from 'lodash/toLower.js';
import Scheduler from '../services/SchedulerService.js';
import startCase from 'lodash/startCase.js';
Expand All @@ -9,6 +10,7 @@ import {
ColorResolvable,
ComponentType,
EmbedBuilder,
Interaction,
Message,
MessageActionRowComponent,
NewsChannel,
Expand All @@ -21,6 +23,8 @@ import { DeveloperIds, REGEX, StaffIds, SupporterIds, LINKS, colors, emojis } fr
import { randomBytes } from 'crypto';
import { t } from './Locale.js';
import 'dotenv/config';
import { captureException } from '@sentry/node';
import { CustomID } from './CustomID.js';

/** Convert milliseconds to a human readable time (eg: 1d 2h 3m 4s) */
export function msToReadable(milliseconds: number): string {
Expand Down Expand Up @@ -271,3 +275,28 @@ export function channelMention(channelId: Snowflake | null | undefined) {
if (!channelId) return emojis.no;
return `<#${channelId}>`;
}

export function handleError(e: Error, interaction?: Interaction) {
// log the error to the system
Logger.error(e);
let extra;

if (interaction) {
extra = {
user: { id: interaction.user.id, username: interaction.user.username },
extra: {
type: interaction.type,
identifier:
interaction.isCommand() || interaction.isAutocomplete()
? interaction.commandName
: CustomID.parseCustomId(interaction.customId),
},
};
}

// capture the error to Sentry.io with additional information
captureException(e, extra);

// reply with an error message to the user
if (interaction?.isRepliable()) replyWithError(interaction, String(e));
}

0 comments on commit ec37481

Please sign in to comment.