From db298dc4cb759f4e71f7e5c6274b1cd2316fe52b Mon Sep 17 00:00:00 2001 From: eduardozgz Date: Fri, 29 Nov 2024 20:10:41 +0100 Subject: [PATCH] Simplify errors --- apps/bot/src/@types/resources.d.ts | 30 +++++++++-- apps/bot/src/events/interactionCreate.ts | 10 +--- apps/bot/src/interactions/commands/profile.ts | 5 +- apps/bot/src/jobs/updateChannels.ts | 7 ++- apps/bot/src/locales/en-US/main.json | 30 +++++++++-- apps/website/src/@types/resources.d.ts | 54 +++++++++---------- apps/website/src/hooks/useShowError.ts | 30 +++++++++++ apps/website/src/i18n/locales/en-US/main.json | 54 +++++++++---------- .../common/src/KnownError/DataSourceError.ts | 5 +- packages/common/src/KnownError/UserError.ts | 7 ++- packages/common/src/KnownError/index.ts | 17 ++++-- .../evaluators/Memerator.ts | 8 +-- .../DataSourceEvaluator/evaluators/Twitch.ts | 18 ++----- .../DataSourceEvaluator/evaluators/YouTube.ts | 18 ++----- .../DataSourceEvaluator/evaluators/game.ts | 15 ++---- .../DataSourceEvaluator/evaluators/http.ts | 23 ++------ .../DataSourceEvaluator/evaluators/members.ts | 18 ++----- .../DataSourceEvaluator/evaluators/reddit.ts | 8 +-- packages/services/src/DataSource/index.ts | 32 +++-------- 19 files changed, 184 insertions(+), 205 deletions(-) create mode 100644 apps/website/src/hooks/useShowError.ts diff --git a/apps/bot/src/@types/resources.d.ts b/apps/bot/src/@types/resources.d.ts index 8a3ac3554..f069399ac 100644 --- a/apps/bot/src/@types/resources.d.ts +++ b/apps/bot/src/@types/resources.d.ts @@ -178,10 +178,32 @@ interface Resources { "computeError": "ERROR!" } }, - "errors": { - "UserError": { - "USER_NOT_FOUND": "User not found." - } + "knownErrors": { + "USER_NOT_FOUND": "User not found.", + "UNKNOWN": "An unknown error occurred.", + "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", + "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", + "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", + "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", + "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", + "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", + "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", + "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", + "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", + "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", + "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", + "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", + "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", + "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", + "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", + "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", + "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", + "GAME_MISSING_ADDRESS": "The game counter requires a server address.", + "GAME_MISSING_PORT": "The game counter requires a server port.", + "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", + "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", + "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", + "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." } } } diff --git a/apps/bot/src/events/interactionCreate.ts b/apps/bot/src/events/interactionCreate.ts index 21f3614bc..b01a63679 100644 --- a/apps/bot/src/events/interactionCreate.ts +++ b/apps/bot/src/events/interactionCreate.ts @@ -56,14 +56,8 @@ export const interactionCreateEvent = new EventHandler({ description.replaceAll("{{ERROR_ID}}", inlineCode(id)), ); - if ( - error instanceof KnownError && - i18n && - error.cause.type === "UserError" - ) { - embed.setDescription( - i18n.t(`errors.${error.cause.type}.${error.cause.name}`), - ); + if (error instanceof KnownError && i18n) { + embed.setDescription(i18n.t(`knownErrors.${error.message}`)); } logger.error(`Interaction error`, { error, interaction }); diff --git a/apps/bot/src/interactions/commands/profile.ts b/apps/bot/src/interactions/commands/profile.ts index 21ed37164..ed79de572 100644 --- a/apps/bot/src/interactions/commands/profile.ts +++ b/apps/bot/src/interactions/commands/profile.ts @@ -89,10 +89,7 @@ export const profileCommand = new Command({ targetUser.id, ).catch((error) => { if (error instanceof NotFoundError) { - throw new KnownError({ - type: "UserError", - name: "USER_NOT_FOUND", - }); + throw new KnownError("USER_NOT_FOUND"); } throw error; }); diff --git a/apps/bot/src/jobs/updateChannels.ts b/apps/bot/src/jobs/updateChannels.ts index 36096b616..caf5dbc77 100644 --- a/apps/bot/src/jobs/updateChannels.ts +++ b/apps/bot/src/jobs/updateChannels.ts @@ -44,10 +44,9 @@ async function updateGuildChannels( await GuildSettingsService.channels.logs .set(channel.id, { LastTemplateUpdateDate: new Date(), - LastTemplateComputeError: new KnownError({ - type: "DataSourceError", - name: "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL", - }).message, + LastTemplateComputeError: new KnownError( + "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL", + ).message, }) .catch(logger.error); diff --git a/apps/bot/src/locales/en-US/main.json b/apps/bot/src/locales/en-US/main.json index de56ba01e..41016ece9 100644 --- a/apps/bot/src/locales/en-US/main.json +++ b/apps/bot/src/locales/en-US/main.json @@ -177,9 +177,31 @@ "computeError": "ERROR!" } }, - "errors": { - "UserError": { - "USER_NOT_FOUND": "User not found." - } + "knownErrors": { + "USER_NOT_FOUND": "User not found.", + "UNKNOWN": "An unknown error occurred.", + "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", + "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", + "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", + "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", + "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", + "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", + "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", + "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", + "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", + "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", + "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", + "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", + "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", + "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", + "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", + "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", + "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", + "GAME_MISSING_ADDRESS": "The game counter requires a server address.", + "GAME_MISSING_PORT": "The game counter requires a server port.", + "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", + "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", + "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", + "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." } } diff --git a/apps/website/src/@types/resources.d.ts b/apps/website/src/@types/resources.d.ts index 5b2e54123..3f197ff04 100644 --- a/apps/website/src/@types/resources.d.ts +++ b/apps/website/src/@types/resources.d.ts @@ -588,33 +588,33 @@ interface Resources { "forumChannel": "Forum channel", "mediaChannel": "Media channel" }, - "errors": { - "DataSourceError": { - "UNKNOWN": "An unknown error occurred.", - "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", - "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", - "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", - "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", - "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", - "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", - "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", - "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", - "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", - "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", - "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", - "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", - "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", - "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", - "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", - "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", - "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", - "GAME_MISSING_ADDRESS": "The game counter requires a server address.", - "GAME_MISSING_PORT": "The game counter requires a server port.", - "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", - "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", - "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", - "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." - } + "knownError": "Error", + "knownErrors": { + "USER_NOT_FOUND": "User not found.", + "UNKNOWN": "An unknown error occurred.", + "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", + "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", + "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", + "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", + "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", + "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", + "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", + "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", + "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", + "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", + "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", + "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", + "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", + "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", + "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", + "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", + "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", + "GAME_MISSING_ADDRESS": "The game counter requires a server address.", + "GAME_MISSING_PORT": "The game counter requires a server port.", + "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", + "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", + "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", + "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." } }, "dataSourceMetadata": { diff --git a/apps/website/src/hooks/useShowError.ts b/apps/website/src/hooks/useShowError.ts new file mode 100644 index 000000000..98a2009dc --- /dev/null +++ b/apps/website/src/hooks/useShowError.ts @@ -0,0 +1,30 @@ +import { TRPCClientError } from "@trpc/client"; +import { useTranslation } from "react-i18next"; +import { z } from "zod"; + +import { KnownErrorsTypeNames } from "@mc/common/KnownError/index"; +import { useToast } from "@mc/ui/hooks/use-toast"; + +export default function useShowError() { + const { t } = useTranslation(); + const { toast } = useToast(); + + const showUnknown = (error: unknown): unknown => { + toast({ title: t("common.unknownError"), variant: "destructive" }); + return error; + }; + + return (error: unknown) => { + if (!(error instanceof TRPCClientError)) throw showUnknown(error); + + const errorMessage = z.enum(KnownErrorsTypeNames).safeParse(error.message); + + if (!errorMessage.success) throw showUnknown(error); + + toast({ + title: t(`common.knownError`), + description: t(`common.knownErrors.${errorMessage.data}`), + variant: "destructive", + }); + }; +} diff --git a/apps/website/src/i18n/locales/en-US/main.json b/apps/website/src/i18n/locales/en-US/main.json index 0d4f42afe..a5a29f9e4 100644 --- a/apps/website/src/i18n/locales/en-US/main.json +++ b/apps/website/src/i18n/locales/en-US/main.json @@ -587,33 +587,33 @@ "forumChannel": "Forum channel", "mediaChannel": "Media channel" }, - "errors": { - "DataSourceError": { - "UNKNOWN": "An unknown error occurred.", - "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", - "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", - "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", - "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", - "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", - "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", - "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", - "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", - "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", - "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", - "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", - "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", - "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", - "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", - "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", - "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", - "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", - "GAME_MISSING_ADDRESS": "The game counter requires a server address.", - "GAME_MISSING_PORT": "The game counter requires a server port.", - "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", - "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", - "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", - "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." - } + "knownError": "Error", + "knownErrors": { + "USER_NOT_FOUND": "User not found.", + "UNKNOWN": "An unknown error occurred.", + "UNKNOWN_DATA_SOURCE": "The counter provided is unknown or not recognized.", + "UNKNOWN_EVALUATION_RETURN_TYPE": "The type of value returned from evaluation is unknown.", + "FAILED_TO_RETURN_A_FINAL_STRING": "Failed to generate a final string from the evaluation.", + "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON": "The counter is in a unrecognized format", + "DELIMITED_DATA_SOURCE_IS_INVALID": "The counter is invalid.", + "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS": "The result for the channel name is less than 2 characters long.", + "NO_ENOUGH_PERMISSIONS_TO_EDIT_CHANNEL": "The bot does not have sufficient permissions to edit the channel.", + "MEMERATOR_MISSING_USERNAME": "The Memerator counter requires a username, which is missing.", + "REDDIT_MISSING_SUBREDDIT": "A subreddit must be provided for the Reddit coutner.", + "TWITCH_MISSING_USERNAME": "The Twitch counter requires a username to be set.", + "TWITCH_CHANNEL_NOT_FOUND": "The specified Twitch channel could not be found.", + "YOUTUBE_MISSING_CHANNEL_URL": "The YouTube counter requires a channel URL to be set.", + "YOUTUBE_INVALID_CHANNEL_URL": "The provided YouTube channel URL is invalid.", + "HTTP_MISSING_URL": "The HTTP counter requires a URL, which is missing.", + "HTTP_INVALID_RESPONSE_CONTENT_TYPE": "The content type of the HTTP response is invalid (not text/plain or application/json).", + "HTTP_INVALID_RESPONSE_STATUS_CODE": "The HTTP response status code is invalid (not 200).", + "HTTP_DATA_PATH_MANDATORY": "A data path must be specified for HTTP requests whose content type is application/json.", + "GAME_MISSING_ADDRESS": "The game counter requires a server address.", + "GAME_MISSING_PORT": "The game counter requires a server port.", + "GAME_MISSING_GAME_ID": "A game ID must be provided for the game counter.", + "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS": "The bot does not have enough privileged intents to use this counter.", + "BOT_IS_NOT_PREMIUM": "The bot is not a premium version and lacks certain features needed for this counter.", + "MEMBER_COUNT_NOT_AVAILABLE": "The member counts are not available at this moment." } }, "dataSourceMetadata": { diff --git a/packages/common/src/KnownError/DataSourceError.ts b/packages/common/src/KnownError/DataSourceError.ts index 66875f2e3..5874e55ba 100644 --- a/packages/common/src/KnownError/DataSourceError.ts +++ b/packages/common/src/KnownError/DataSourceError.ts @@ -25,7 +25,4 @@ export const DataSourceErrorNames = [ "MEMBER_COUNT_NOT_AVAILABLE", ] as const; -export interface DataSourceError { - type: "DataSourceError"; - name: (typeof DataSourceErrorNames)[number]; -} +export type DataSourceError = (typeof DataSourceErrorNames)[number]; diff --git a/packages/common/src/KnownError/UserError.ts b/packages/common/src/KnownError/UserError.ts index 6ba05e016..f1dcbfb0a 100644 --- a/packages/common/src/KnownError/UserError.ts +++ b/packages/common/src/KnownError/UserError.ts @@ -1,4 +1,3 @@ -export interface UserError { - type: "UserError"; - name: "USER_NOT_FOUND"; -} +export const UserErrorNames = ["USER_NOT_FOUND"] as const; + +export type UserError = (typeof UserErrorNames)[number]; diff --git a/packages/common/src/KnownError/index.ts b/packages/common/src/KnownError/index.ts index 2fcc5fc0b..b7df8c693 100644 --- a/packages/common/src/KnownError/index.ts +++ b/packages/common/src/KnownError/index.ts @@ -1,10 +1,17 @@ -import type { DataSourceError } from "./DataSourceError"; -import type { UserError } from "./UserError"; +import { DataSourceErrorNames } from "./DataSourceError"; +import { UserErrorNames } from "./UserError"; -export type ErrorCause = DataSourceError | UserError; +export const KnownErrorsTypeNames = [ + ...DataSourceErrorNames, + ...UserErrorNames, +] as const; +export type KnownErrorType = (typeof KnownErrorsTypeNames)[number]; export class KnownError extends Error { - constructor(public cause: ErrorCause) { - super(cause.type, { cause }); + constructor( + public message: KnownErrorType, + options?: ErrorOptions, + ) { + super(message, options); } } diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Memerator.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Memerator.ts index 29b23a5bd..5ce710d2f 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Memerator.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Memerator.ts @@ -70,13 +70,7 @@ async function fetchData( export const memeratorEvaluator = new DataSourceEvaluator({ id: DataSourceId.MEMERATOR, execute: async ({ options }) => { - assert( - options.username, - new KnownError({ - type: "DataSourceError", - name: "MEMERATOR_MISSING_USERNAME", - }), - ); + assert(options.username, new KnownError("MEMERATOR_MISSING_USERNAME")); return Number(await fetchData(options.username, options.return)); }, diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Twitch.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Twitch.ts index 6c8609923..97cb96b22 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Twitch.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/Twitch.ts @@ -58,10 +58,7 @@ async function fetchData( const channel = await client.users.getUserByName(username); if (!channel) { - throw new KnownError({ - type: "DataSourceError", - name: "TWITCH_CHANNEL_NOT_FOUND", - }); + throw new KnownError("TWITCH_CHANNEL_NOT_FOUND"); } const stream = await client.streams.getStreamByUserName(username); @@ -107,17 +104,8 @@ export const twitchEvaluator = new DataSourceEvaluator({ id: DataSourceId.TWITCH, execute: ({ ctx, options }) => { const { isPremium } = ctx.guild.client.botInstanceOptions; - assert( - isPremium, - new KnownError({ type: "DataSourceError", name: "BOT_IS_NOT_PREMIUM" }), - ); - assert( - options.username, - new KnownError({ - type: "DataSourceError", - name: "TWITCH_MISSING_USERNAME", - }), - ); + assert(isPremium, new KnownError("BOT_IS_NOT_PREMIUM")); + assert(options.username, new KnownError("TWITCH_MISSING_USERNAME")); return fetchData(options.username, options.return); }, diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/YouTube.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/YouTube.ts index 21a04bc16..7459a08c0 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/YouTube.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/YouTube.ts @@ -163,18 +163,9 @@ export const youTubeEvaluator = new DataSourceEvaluator({ id: DataSourceId.YOUTUBE, execute: async ({ ctx, options: { channelUrl, return: returnType } }) => { const { isPremium } = ctx.guild.client.botInstanceOptions; - assert( - isPremium, - new KnownError({ type: "DataSourceError", name: "BOT_IS_NOT_PREMIUM" }), - ); + assert(isPremium, new KnownError("BOT_IS_NOT_PREMIUM")); assert(env.YOUTUBE_API_KEY, new Error("YOUTUBE_API_KEY not provided")); - assert( - channelUrl, - new KnownError({ - type: "DataSourceError", - name: "YOUTUBE_MISSING_CHANNEL_URL", - }), - ); + assert(channelUrl, new KnownError("YOUTUBE_MISSING_CHANNEL_URL")); let searchChannel: string | undefined = ""; let searchChannelBy: "id" | "forUsername" | undefined; @@ -194,10 +185,7 @@ export const youTubeEvaluator = new DataSourceEvaluator({ assert( searchChannel && searchChannelBy, - new KnownError({ - type: "DataSourceError", - name: "YOUTUBE_INVALID_CHANNEL_URL", - }), + new KnownError("YOUTUBE_INVALID_CHANNEL_URL"), ); return await fetchData(searchChannel, searchChannelBy, returnType); diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/game.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/game.ts index 96e37dfde..d15320fe1 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/game.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/game.ts @@ -9,18 +9,9 @@ import { DataSourceEvaluator } from ".."; export const gameEvaluator = new DataSourceEvaluator({ id: DataSourceId.GAME, execute: async ({ options }) => { - assert( - options.address, - new KnownError({ type: "DataSourceError", name: "GAME_MISSING_ADDRESS" }), - ); - assert( - options.port, - new KnownError({ type: "DataSourceError", name: "GAME_MISSING_PORT" }), - ); - assert( - options.game, - new KnownError({ type: "DataSourceError", name: "GAME_MISSING_GAME_ID" }), - ); + assert(options.address, new KnownError("GAME_MISSING_ADDRESS")); + assert(options.port, new KnownError("GAME_MISSING_PORT")); + assert(options.game, new KnownError("GAME_MISSING_GAME_ID")); const response = await GameDig.query({ type: options.game, diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/http.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/http.ts index f19ce46d5..932197700 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/http.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/http.ts @@ -33,20 +33,14 @@ async function fetchData(url: string, lifetime?: number) { assert( response.status === 200, - new KnownError({ - type: "DataSourceError", - name: "HTTP_INVALID_RESPONSE_STATUS_CODE", - }), + new KnownError("HTTP_INVALID_RESPONSE_STATUS_CODE"), ); const contentType = response.headers.get("Content-Type")?.split(";")[0] ?? ""; assert( ["text/plain", "application/json"].includes(contentType), - new KnownError({ - type: "DataSourceError", - name: "HTTP_INVALID_RESPONSE_CONTENT_TYPE", - }), + new KnownError("HTTP_INVALID_RESPONSE_CONTENT_TYPE"), ); const body = await response.text(); @@ -63,10 +57,7 @@ async function fetchData(url: string, lifetime?: number) { export const HTTPEvaluator = new DataSourceEvaluator({ id: DataSourceId.HTTP, execute: async ({ options }) => { - assert( - options.url, - new KnownError({ type: "DataSourceError", name: "HTTP_MISSING_URL" }), - ); + assert(options.url, new KnownError("HTTP_MISSING_URL")); const { body, contentType } = await fetchData( options.url, @@ -74,13 +65,7 @@ export const HTTPEvaluator = new DataSourceEvaluator({ ); if (contentType === "application/json") { - assert( - options.dataPath, - new KnownError({ - type: "DataSourceError", - name: "HTTP_DATA_PATH_MANDATORY", - }), - ); + assert(options.dataPath, new KnownError("HTTP_DATA_PATH_MANDATORY")); return jsonBodyExtractor(JSON.parse(body), options.dataPath); } else { diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/members.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/members.ts index 5eff00301..1bcff2b58 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/members.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/members.ts @@ -23,16 +23,8 @@ const PresenceStatusMap: Record = { const throwAvailabiltyIssue = (ctx: DataSourceContext) => { const { isPremium } = ctx.guild.client.botInstanceOptions; - if (isPremium) - throw new KnownError({ - type: "DataSourceError", - name: "BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS", - }); - else - throw new KnownError({ - type: "DataSourceError", - name: "BOT_IS_NOT_PREMIUM", - }); + if (isPremium) throw new KnownError("BOT_HAS_NO_ENOUGH_PRIVILEGED_INTENTS"); + else throw new KnownError("BOT_IS_NOT_PREMIUM"); }; const executeUnprivilegedSearch: DataSourceEvaluator["execute"] = @@ -59,11 +51,7 @@ const executeUnprivilegedSearch: DataSourceEvaluator["exec throwAvailabiltyIssue(ctx); } - if (!count) - throw new KnownError({ - type: "DataSourceError", - name: "MEMBER_COUNT_NOT_AVAILABLE", - }); + if (!count) throw new KnownError("MEMBER_COUNT_NOT_AVAILABLE"); return count; }; diff --git a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/reddit.ts b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/reddit.ts index b2f97cc05..3d2515010 100644 --- a/packages/services/src/DataSource/DataSourceEvaluator/evaluators/reddit.ts +++ b/packages/services/src/DataSource/DataSourceEvaluator/evaluators/reddit.ts @@ -89,13 +89,7 @@ async function fetchData( export const redditEvaluator = new DataSourceEvaluator({ id: DataSourceId.REDDIT, execute: async ({ options }) => { - assert( - options.subreddit, - new KnownError({ - type: "DataSourceError", - name: "REDDIT_MISSING_SUBREDDIT", - }), - ); + assert(options.subreddit, new KnownError("REDDIT_MISSING_SUBREDDIT")); return await fetchData(options.subreddit, options.return); }, diff --git a/packages/services/src/DataSource/index.ts b/packages/services/src/DataSource/index.ts index 6ed4d4df5..0a39bc6ed 100644 --- a/packages/services/src/DataSource/index.ts +++ b/packages/services/src/DataSource/index.ts @@ -48,10 +48,9 @@ class DataSourceService { result = result.slice(0, 1023); } else { if (result.length < 2) - throw new KnownError({ - type: "DataSourceError", - name: "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS", - }); + throw new KnownError( + "EVALUATION_RESULT_FOR_CHANNEL_NAME_IS_LESS_THAN_2_CHARACTERS", + ); result = result.slice(0, 99); } @@ -87,10 +86,7 @@ class DataSourceService { assert( typeof result === "number" || typeof result === "string", - new KnownError({ - type: "DataSourceError", - name: "UNKNOWN_EVALUATION_RETURN_TYPE", - }), + new KnownError("UNKNOWN_EVALUATION_RETURN_TYPE"), ); if (typeof result === "number" && !isNaN(result)) { @@ -119,10 +115,7 @@ class DataSourceService { assert( typeof result === "string", - new KnownError({ - type: "DataSourceError", - name: "FAILED_TO_RETURN_A_FINAL_STRING", - }), + new KnownError("FAILED_TO_RETURN_A_FINAL_STRING"), ); return result; @@ -192,10 +185,7 @@ class DataSourceService { }): Promise { const dataSourceEvaluator = DataSourceService.dataSourceEvaluators[id]; - assert( - dataSourceEvaluator, - new KnownError({ type: "DataSourceError", name: "UNKNOWN_DATA_SOURCE" }), - ); + assert(dataSourceEvaluator, new KnownError("UNKNOWN_DATA_SOURCE")); return await dataSourceEvaluator.execute({ format, @@ -210,17 +200,11 @@ class DataSourceService { try { parsed = JSON.parse(unparsedRawDataSource) as DataSource; } catch { - throw new KnownError({ - type: "DataSourceError", - name: "DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON", - }); + throw new KnownError("DELIMITED_DATA_SOURCE_IS_ILLEGAL_JSON"); } if (!Object.prototype.hasOwnProperty.call(parsed, "id")) - throw new KnownError({ - type: "DataSourceError", - name: "DELIMITED_DATA_SOURCE_IS_INVALID", - }); + throw new KnownError("DELIMITED_DATA_SOURCE_IS_INVALID"); return parsed; }