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