feat: user error discrimination

This commit is contained in:
TrèsAbhi committed 2023-10-17 20:58:36 -05:00
1 parent f9e0584f00
commit 4b00e1342e
11 files changed
+49 -51

No files matched your search

+10 -7
View File
@@ -18,7 +18,7 @@ import getMidnightLeaderboard, {
DATABASE_REPO, DATABASE_REPO,
} from '../core/blitzkrieg/getMidnightLeaderboard'; } from '../core/blitzkrieg/getMidnightLeaderboard';
import { octokit } from '../core/blitzkrieg/octokit'; import { octokit } from '../core/blitzkrieg/octokit';
import throwError from '../core/blitzkrieg/throwError'; import { UserError } from '../core/blitzkrieg/userError';
import addRegionChoices from '../core/discord/addRegionChoices'; import addRegionChoices from '../core/discord/addRegionChoices';
import addUsernameChoices from '../core/discord/addUsernameChoices'; import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteUsername from '../core/discord/autocompleteUsername'; import autocompleteUsername from '../core/discord/autocompleteUsername';
@@ -185,7 +185,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
}) })
.then(({ data }) => { .then(({ data }) => {
if (!Array.isArray(data)) { if (!Array.isArray(data)) {
throw throwError('Archived ratings data is malformed'); throw new Error('Archived ratings data is malformed');
} }
return data.map( return data.map(
(folder) => (folder) =>
@@ -292,7 +292,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
}) })
.then(async ({ data }) => { .then(async ({ data }) => {
if (Array.isArray(data) || data.type !== 'file') { if (Array.isArray(data) || data.type !== 'file') {
throw throwError('Archived ratings data is malformed'); throw new Error('Archived ratings data is malformed');
} }
const players = (await fetch(data.download_url!).then( const players = (await fetch(data.download_url!).then(
@@ -361,7 +361,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
}) })
.then(async ({ data }) => { .then(async ({ data }) => {
if (Array.isArray(data) || data.type !== 'file') { if (Array.isArray(data) || data.type !== 'file') {
throw throwError('Archived ratings info is malformed'); throw new Error('Archived ratings info is malformed');
} }
const response = fetch(data.download_url!); const response = fetch(data.download_url!);
@@ -404,7 +404,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
}) })
.then(async ({ data }) => { .then(async ({ data }) => {
if (Array.isArray(data) || data.type !== 'file') { if (Array.isArray(data) || data.type !== 'file') {
throw throwError( throw new Error(
'Archived ratings latest data is malformed', 'Archived ratings latest data is malformed',
); );
} }
@@ -418,9 +418,12 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
); );
if (playerIndex === -1) { if (playerIndex === -1) {
throw throwError( throw new UserError(
`${accountInfo.nickname} didn't player ratings in season ${season}`, `${accountInfo.nickname} didn't player ratings in season ${season}`,
'This player did not participate in this season or did not get past calibration.', {
cause:
'This player did not participate in this season or did not get past calibration.',
},
); );
} }
+3 -6
View File
@@ -1,5 +1,3 @@
import throwError from '../blitzkrieg/throwError';
export type BlitzResponse<Data extends object> = export type BlitzResponse<Data extends object> =
| { | {
status: 'error'; status: 'error';
@@ -18,9 +16,8 @@ export default async function fetchBlitz<Data extends object>(url: string) {
if (data.status === 'ok') { if (data.status === 'ok') {
return data.data; return data.data;
} else { } else {
throw throwError( throw new Error(`Wargaming response error status:"${data.status}"`, {
`Wargaming response error status:"${data.status}"`, cause: `Message: "${data.error.message}"\nURL: "${url}"`,
`Message: "${data.error.message}"\nURL: "${url}"`, });
);
} }
} }
+5 -5
View File
@@ -1,7 +1,7 @@
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID'; import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
import { TanksStats } from '../../types/tanksStats'; import { TanksStats } from '../../types/tanksStats';
import throwError from '../blitzkrieg/throwError'; import { UserError } from '../blitzkrieg/userError';
import fetchBlitz from './fetchWargaming'; import fetchBlitz from './fetchWargaming';
export default async function getTankStats(region: Region, id: number) { export default async function getTankStats(region: Region, id: number) {
@@ -10,10 +10,10 @@ export default async function getTankStats(region: Region, id: number) {
); );
if (tankStats[id] === null) { if (tankStats[id] === null) {
throw throwError( throw new UserError('No tank stats available', {
'No tank stats available', cause:
"This player doesn't have any stats for tanks available. This may not be the player you are looking for.", "This player doesn't have any stats for tanks available. This may not be the player you are looking for.",
); });
} }
return tankStats[id]; return tankStats[id];
+7 -9
View File
@@ -1,5 +1,5 @@
import { go } from 'fuzzysort'; import { go } from 'fuzzysort';
import throwError from '../blitzkrieg/throwError'; import { UserError } from '../blitzkrieg/userError';
import { TANKS, tankopedia } from '../blitzstars/tankopedia'; import { TANKS, tankopedia } from '../blitzstars/tankopedia';
export default async function resolveTankId(tank: string | number) { export default async function resolveTankId(tank: string | number) {
@@ -12,10 +12,9 @@ export default async function resolveTankId(tank: string | number) {
}); });
if (searchResult.length === 0) { if (searchResult.length === 0) {
throw throwError( throw new UserError('Tank not found', {
'Tank not found', cause: `Could not find tank by the name "${tank}".`,
`Could not find tank by the name "${tank}".`, });
);
} else { } else {
return searchResult[0].obj.tank_id; return searchResult[0].obj.tank_id;
} }
@@ -23,10 +22,9 @@ export default async function resolveTankId(tank: string | number) {
if ((await tankopedia)[number]) { if ((await tankopedia)[number]) {
return number; return number;
} else { } else {
throw throwError( throw new UserError('Tank not found', {
'Tank not found', cause: `Could not find tank by the ID "${number}".`,
`Could not find tank by the ID "${number}".`, });
);
} }
} }
} }
@@ -2,7 +2,6 @@ import { RatingsInfo } from '../../commands/ratings';
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import { DATABASE_REPO } from './getMidnightLeaderboard'; import { DATABASE_REPO } from './getMidnightLeaderboard';
import { octokit } from './octokit'; import { octokit } from './octokit';
import throwError from './throwError';
const ARCHIVED_RATINGS_CACHE: Record< const ARCHIVED_RATINGS_CACHE: Record<
Region, Region,
@@ -32,7 +31,7 @@ export default async function getArchivedRatingsInfo(
}); });
if (Array.isArray(data) || data.type !== 'file') if (Array.isArray(data) || data.type !== 'file')
throw throwError('Archived ratings info is malformed'); throw new Error('Archived ratings info is malformed');
const content = Buffer.from(data.content, 'base64').toString(); const content = Buffer.from(data.content, 'base64').toString();
const jsonContent = JSON.parse(content) as RatingsInfo & { const jsonContent = JSON.parse(content) as RatingsInfo & {
-3
View File
@@ -1,3 +0,0 @@
export default function throwError(message: string, cause?: string) {
return new Error(message, { cause });
}
+4
View File
@@ -0,0 +1,4 @@
/**
* Discriminator for user caused errors to not report in logs
*/
export class UserError extends Error {}
+4 -5
View File
@@ -1,7 +1,7 @@
import { ChatInputCommandInteraction } from 'discord.js'; import { ChatInputCommandInteraction } from 'discord.js';
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions'; import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions';
import throwError from '../blitzkrieg/throwError'; import { UserError } from '../blitzkrieg/userError';
import { serverAndIdPattern } from './resolvePlayerFromCommand'; import { serverAndIdPattern } from './resolvePlayerFromCommand';
export default async function resolveClanFromCommand( export default async function resolveClanFromCommand(
@@ -18,10 +18,9 @@ export default async function resolveClanFromCommand(
if (accounts[0]) { if (accounts[0]) {
return { region: accounts[0].region, id: accounts[0].clan_id }; return { region: accounts[0].region, id: accounts[0].clan_id };
} else { } else {
throw throwError( throw new UserError('Could not find clan', {
'Could not find clan', cause: `I couldn't find clan \`${clan}\`. Try selecting a username from the search result.`,
`I couldn't find clan \`${clan}\`. Try selecting a username from the search result.`, });
);
} }
} }
} }
+9 -9
View File
@@ -3,7 +3,7 @@ import markdownEscape from 'markdown-escape';
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions'; import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions';
import { getBlitzFromDiscord } from '../blitzkrieg/discordBlitz'; import { getBlitzFromDiscord } from '../blitzkrieg/discordBlitz';
import throwError from '../blitzkrieg/throwError'; import { UserError } from '../blitzkrieg/userError';
export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/; export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
@@ -34,12 +34,11 @@ export default async function resolvePlayerFromCommand(
id: accounts[0].account_id, id: accounts[0].account_id,
} satisfies ResolvedPlayer; } satisfies ResolvedPlayer;
} else { } else {
throw throwError( throw new UserError('Could not find user', {
'Could not find user', cause: `I couldn't find user "${markdownEscape(
`I couldn't find user "${markdownEscape(
commandUsername, commandUsername,
)}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`, )}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`,
); });
} }
} }
} else { } else {
@@ -48,10 +47,11 @@ export default async function resolvePlayerFromCommand(
if (account) { if (account) {
return { region: account.region, id: account.blitz }; return { region: account.region, id: account.blitz };
} else { } else {
throw throwError( // TODO: simplify message
"You're not linked", throw new UserError("You're not linked", {
'Use the `/link` command to link your Discord and Blitz accounts.', cause:
); 'Use the `/link` command to link your Discord and Blitz accounts.',
});
} }
} }
} }
@@ -1,6 +1,5 @@
import { ButtonInteraction, CacheType } from 'discord.js'; import { ButtonInteraction, CacheType } from 'discord.js';
import { commands } from '..'; import { commands } from '..';
import throwError from '../../../core/blitzkrieg/throwError';
import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable'; import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable';
export default async function handleButton( export default async function handleButton(
@@ -13,8 +12,7 @@ export default async function handleButton(
const button = (await commands)[commandName]?.button; const button = (await commands)[commandName]?.button;
if (!button) { if (!button) {
throwError(`Button handler not found for "${commandName}"`); throw new Error(`Button handler not found for "${commandName}"`);
return;
} }
if (interaction.message.interaction?.user.id !== interaction.user.id) { if (interaction.message.interaction?.user.id !== interaction.user.id) {
@@ -7,10 +7,11 @@ import {
} from 'discord.js'; } from 'discord.js';
import { commands } from '..'; import { commands } from '..';
import discord from '../../../../discord.json' assert { type: 'json' }; import discord from '../../../../discord.json' assert { type: 'json' };
import { psa } from '../../../core/discord/psa'; import { UserError } from '../../../core/blitzkrieg/userError';
import embedNegative from '../../../core/discord/embedNegative'; import embedNegative from '../../../core/discord/embedNegative';
import embedWarning from '../../../core/discord/embedWarning'; import embedWarning from '../../../core/discord/embedWarning';
import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable'; import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable';
import { psa } from '../../../core/discord/psa';
export default async function handleChatInputCommand( export default async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>, interaction: ChatInputCommandInteraction<CacheType>,
@@ -53,7 +54,9 @@ export default async function handleChatInputCommand(
.setStyle(ButtonStyle.Link), .setStyle(ButtonStyle.Link),
); );
console.error(interaction.commandName, error); if (!(error instanceof UserError)) {
console.error(interaction.commandName, error);
}
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [