feat: better command error reporting

This commit is contained in:
TresAbhi committed 2023-05-06 18:03:37 +00:00
1 parent 5ef1f87236
commit 92acbc8e95
16 files changed
+668 -31

No files matched your search

+3 -3
View File
@@ -7,7 +7,7 @@ import isDev from '../utilities/isDev.js';
const PROCESS_ERROR_EVENTS = ['uncaughtException'];
const CLIENT_ERROR_EVENTS = ['error'];
export function handleError(error: Error, client: Client, command?: string) {
export function handleError(error: Error, client: Client, command: string) {
console.error(error);
(
@@ -31,10 +31,10 @@ export function handleError(error: Error, client: Client, command?: string) {
export function registerErrorHandlers() {
if (!isDev()) {
PROCESS_ERROR_EVENTS.forEach((name) =>
process.on(name, (error) => handleError(error, client)),
process.on(name, (error) => handleError(error, client, 'process error')),
);
CLIENT_ERROR_EVENTS.forEach((name) =>
client.on(name, (error) => handleError(error, client)),
client.on(name, (error) => handleError(error, client, 'client error')),
);
}
+1 -1
View File
@@ -2,9 +2,9 @@ import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
import packageJSON from '../../package.json' assert { type: 'json' };
import { CommandRegistry } from '../behaviors/interactionCreate.js';
import { SKILLED_COLOR } from '../constants/colors.js';
import { client } from '../index.js';
import getClientId from '../utilities/getClientId.js';
import { tankopedia } from '../utilities/tankopedia.js';
import { client } from '../index.js';
const executionStart = new Date().getTime();
+3 -1
View File
@@ -40,10 +40,12 @@ export default {
const name = interaction.options.getString('name')!;
const server = interaction.options.getString('server') as BlitzServer;
const clan = interaction.options.getString('clan') as keyof typeof CLANS;
const command = `eligible ${server} ${name} ${clan}`;
getBlitzAccount(interaction, name, server, async (account) => {
getBlitzAccount(interaction, command, name, server, async (account) => {
getBlitzStarsAccount(
interaction,
command,
account.account_id,
name,
async (data) => {
+5 -2
View File
@@ -14,7 +14,7 @@ const DEFAULT_THRESHOLD = 7;
export default {
inProduction: true,
inDevelopment: true,
inDevelopment: false,
inPublic: true,
command: new SlashCommandBuilder()
@@ -39,8 +39,9 @@ export default {
async execute(interaction) {
const name = interaction.options.getString('name')!;
const server = interaction.options.getString('server') as BlitzServer;
const command = `inactive ${server} ${name}`;
getClan(interaction, name, server, async (clan) => {
getClan(interaction, command, name, server, async (clan) => {
const threshold =
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
const time = new Date().getTime() / 1000;
@@ -48,6 +49,7 @@ export default {
getWargamingResponse<ClanInfo>(
`https://api.wotblitz.${server}/wotb/clans/info/?application_id=${args['wargaming-application-id']}&clan_id=${clan.clan_id}`,
interaction,
command,
async (clanInfo) => {
const memberIds = clanInfo[clan.clan_id].members_ids;
@@ -56,6 +58,7 @@ export default {
args['wargaming-application-id']
}&account_id=${memberIds.join(',')}`,
interaction,
command,
async (playerPersonalData) => {
const inactiveInfo = memberIds
.map((memberId) => {
+2
View File
@@ -30,10 +30,12 @@ export default {
const server = interaction.options.getString('server')!;
const name = interaction.options.getString('name')!;
const limit = interaction.options.getInteger('limit') ?? 25;
const command = `searchplayers ${server} ${name} ${limit}`;
getWargamingResponse<Players>(
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}&limit=${limit}`,
interaction,
command,
(players) => {
interaction.editReply({
embeds: [
+3 -1
View File
@@ -39,10 +39,12 @@ export default {
| '30'
| '90'
| 'career';
const command = `stats ${server} ${name} ${period}`;
getBlitzAccount(interaction, name, server, async (account) => {
getBlitzAccount(interaction, command, name, server, async (account) => {
getBlitzStarsAccount(
interaction,
command,
account.account_id,
name,
async (data) => {
+3 -1
View File
@@ -55,11 +55,13 @@ export default {
const server = interaction.options.getString('server') as BlitzServer;
const name = interaction.options.getString('name')!;
const tier = interaction.options.getInteger('tier')!;
const command = `tanks ${server} ${name} ${tier}`;
getBlitzAccount(interaction, name, server, async (account) => {
getBlitzAccount(interaction, command, name, server, async (account) => {
getWargamingResponse<TanksStats>(
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}`,
interaction,
command,
async (tankStats) => {
const tanks = tankStats[account.account_id]!.map(
(tankData) => tankopedia.data[tankData.tank_id],
+3 -1
View File
@@ -25,11 +25,13 @@ export default {
execute(interaction) {
const name = interaction.options.getString('name')!;
const server = interaction.options.getString('server') as BlitzServer;
const command = `verify ${server} ${name}`;
getBlitzAccount(interaction, name, server, async (account) => {
getBlitzAccount(interaction, server, name, server, async (account) => {
getWargamingResponse<PlayerClanData>(
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${account.account_id}&extra=clan`,
interaction,
server,
async (clanData) => {
const clan = clanData[account.account_id].clan;
const clanTag = clan === null ? '' : ` [${clan!.tag}]`;
+28
View File
@@ -0,0 +1,28 @@
import {
CacheType,
ChatInputCommandInteraction,
EmbedBuilder,
} from 'discord.js';
import { handleError } from '../behaviors/error.js';
import { NEGATIVE_COLOR } from '../constants/colors.js';
import { client } from '../index.js';
export default async function blitzStarsError(
interaction: ChatInputCommandInteraction<CacheType>,
error: Error,
command: string,
) {
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(NEGATIVE_COLOR)
.setTitle(`${client.user?.username} ran into an issue`)
.setDescription(
'BlitzStars returned an error. Please try again later.',
),
],
});
console.log(`BlitzStars returned an error`);
handleError(error, client, command);
}
+2
View File
@@ -12,6 +12,7 @@ import getWargamingResponse from './getWargamingResponse.js';
export default async function getBlitzAccount(
interaction: ChatInputCommandInteraction<CacheType>,
command: string,
name: string,
server: BlitzServer,
callback: (account: Player) => void,
@@ -21,6 +22,7 @@ export default async function getBlitzAccount(
getWargamingResponse<Players>(
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
interaction,
command,
async (players) => {
if (
players.length > 0 &&
+15 -17
View File
@@ -7,30 +7,17 @@ import markdownEscape from 'markdown-escape';
import fetch from 'node-fetch';
import { NEGATIVE_COLOR } from '../constants/colors.js';
import { PlayerStatistics } from '../types/statistics.js';
import blitzStarsError from './blitzStarsError.js';
export default async function getBlitzStarsAccount(
interaction: ChatInputCommandInteraction<CacheType>,
command: string,
accountId: number,
name: string,
callback: (account: PlayerStatistics) => void,
) {
if (!interaction.deferred) await interaction.deferReply();
async function notTracked() {
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle('No data to display')
.setDescription(
`${markdownEscape(name)} is not tracked by BlitzStars.`,
)
.setColor(NEGATIVE_COLOR),
],
});
console.log(`${name} is not tracked by BlitzStars.`);
}
fetch(`https://www.blitzstars.com/api/top/player/${accountId}`)
.then(async (response) => {
const data = (await response.json()) as PlayerStatistics;
@@ -38,8 +25,19 @@ export default async function getBlitzStarsAccount(
if (data.statistics) {
callback(data);
} else {
notTracked();
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle('No data to display')
.setDescription(
`${markdownEscape(name)} is not tracked by BlitzStars.`,
)
.setColor(NEGATIVE_COLOR),
],
});
console.log(`${name} is not tracked by BlitzStars.`);
}
})
.catch(notTracked);
.catch((error) => blitzStarsError(interaction, error, command));
}
+2
View File
@@ -12,6 +12,7 @@ import getWargamingResponse from './getWargamingResponse.js';
export default async function getClan(
interaction: ChatInputCommandInteraction<CacheType>,
command: string,
name: string,
server: BlitzServer,
callback: (account: Clan) => void,
@@ -21,6 +22,7 @@ export default async function getClan(
getWargamingResponse<ClanList>(
`https://api.wotblitz.${server}/wotb/clans/list/?application_id=${args['wargaming-application-id']}&search=${name}`,
interaction,
command,
async (clans) => {
if (
clans.length > 0 &&
+7 -2
View File
@@ -6,6 +6,7 @@ import wargamingError from './wargamingError.js';
export default async function getWargamingResponse<Data extends object>(
url: string,
interaction: ChatInputCommandInteraction<CacheType>,
command: string,
callback: (data: Data) => void,
) {
if (!interaction.deferred) await interaction.deferReply();
@@ -16,8 +17,12 @@ export default async function getWargamingResponse<Data extends object>(
if (response.status === 'ok') {
callback(response.data);
} else {
wargamingError(interaction, new Error(`Status ${response.status}`));
wargamingError(
interaction,
new Error(`Status ${response.status}`),
command,
);
}
})
.catch((error) => wargamingError(interaction, error));
.catch((error) => wargamingError(interaction, error, command));
}
+2 -1
View File
@@ -10,6 +10,7 @@ import { client } from '../index.js';
export default async function wargamingError(
interaction: ChatInputCommandInteraction<CacheType>,
error: Error,
command: string,
) {
await interaction.editReply({
embeds: [
@@ -21,5 +22,5 @@ export default async function wargamingError(
});
console.log(`Wargaming returned an error`);
handleError(error, client);
handleError(error, client, command);
}