diff --git a/src/commands/utils/metar.ts b/src/commands/utils/metar.ts index d7ef48f6..2cc42e3f 100644 --- a/src/commands/utils/metar.ts +++ b/src/commands/utils/metar.ts @@ -1,7 +1,7 @@ import { ApplicationCommandOptionType, ApplicationCommandType, Colors } from 'discord.js'; import { Request } from 'node-fetch'; import { ZodError } from 'zod'; -import { constantsConfig, fetchForeignAPI, makeEmbed, makeLines, slashCommand, slashCommandStructure, Metar, MetarSchema } from '../../lib'; +import { constantsConfig, fetchForeignAPI, makeEmbed, makeLines, slashCommand, slashCommandStructure, Metar, MetarSchema, Logger } from '../../lib'; const data = slashCommandStructure({ name: 'metar', @@ -41,7 +41,7 @@ export default slashCommand(data, async ({ interaction }) => { let metar: Metar; try { - metar = await fetchForeignAPI(new Request(`https://avwx.rest/api/metar/${icao}`, { + metar = await fetchForeignAPI(new Request(`https://avwx.rest/api/metar/${icao}`, { method: 'GET', headers: { Authorization: metarToken }, }), MetarSchema); @@ -49,6 +49,7 @@ export default slashCommand(data, async ({ interaction }) => { if (e instanceof ZodError) { return interaction.editReply({ embeds: [errorEmbed('The API returned unknown data.')] }); } + Logger.error(`Error occured while fetching METAR: ${String(e)}`); return interaction.editReply({ embeds: [errorEmbed(`An error occurred while fetching the latest METAR for ${icao.toUpperCase()}.`)] }); } diff --git a/src/commands/utils/simbriefData.ts b/src/commands/utils/simbriefData.ts index e9869519..bc66801d 100644 --- a/src/commands/utils/simbriefData.ts +++ b/src/commands/utils/simbriefData.ts @@ -1,7 +1,7 @@ import { ApplicationCommandOptionType, ApplicationCommandType, Colors } from 'discord.js'; import moment from 'moment'; import { ZodError } from 'zod'; -import { fetchForeignAPI, makeEmbed, makeLines, SimbriefFlightPlan, SimbriefFlightPlanSchema, slashCommand, slashCommandStructure } from '../../lib'; +import { fetchForeignAPI, Logger, makeEmbed, makeLines, SimbriefFlightPlan, SimbriefFlightPlanSchema, slashCommand, slashCommandStructure } from '../../lib'; const data = slashCommandStructure({ name: 'simbrief-data', @@ -41,9 +41,9 @@ const simbriefdatarequestEmbed = makeEmbed({ ]), }); -const errorEmbed = (errorMessage: string) => makeEmbed({ +const errorEmbed = (error: string) => makeEmbed({ title: 'SimBrief Error', - description: errorMessage, + description: error, color: Colors.Red, }); @@ -85,6 +85,7 @@ export default slashCommand(data, async ({ interaction }) => { if (e instanceof ZodError) { return interaction.editReply({ embeds: [errorEmbed('The API returned unknown data.')] }); } + Logger.error(`Error while fetching SimBrief flightplan: ${String(e)}`); return interaction.editReply({ embeds: [errorEmbed('An error occurred while fetching the SimBrief flightplan.')] }); } diff --git a/src/commands/utils/station.ts b/src/commands/utils/station.ts index 735093fd..20275e08 100644 --- a/src/commands/utils/station.ts +++ b/src/commands/utils/station.ts @@ -51,7 +51,7 @@ export default slashCommand(data, async ({ interaction }) => { let station: AVWXStation; try { - station = await fetchForeignAPI(new Request(`https://avwx.rest/api/station/${icao}`, { + station = await fetchForeignAPI(new Request(`https://avwx.rest/api/station/${icao}`, { method: 'GET', headers: { Authorization: stationToken }, }), AVWXStationSchema); diff --git a/src/commands/utils/taf.ts b/src/commands/utils/taf.ts index 344d6b8c..96caab98 100644 --- a/src/commands/utils/taf.ts +++ b/src/commands/utils/taf.ts @@ -51,7 +51,7 @@ export default slashCommand(data, async ({ interaction }) => { let taf: TAF; try { - taf = await fetchForeignAPI(new Request(`https://avwx.rest/api/taf/${icao}`, { + taf = await fetchForeignAPI(new Request(`https://avwx.rest/api/taf/${icao}`, { method: 'GET', headers: { Authorization: tafToken }, }), TafSchema); diff --git a/src/commands/utils/vatsim/functions/vatsimEvents.ts b/src/commands/utils/vatsim/functions/vatsimEvents.ts index 0cac5ce6..73b96dd8 100644 --- a/src/commands/utils/vatsim/functions/vatsimEvents.ts +++ b/src/commands/utils/vatsim/functions/vatsimEvents.ts @@ -1,5 +1,5 @@ import { ChatInputCommandInteraction, Colors, EmbedField } from 'discord.js'; -import { Logger, VatsimEvents, VatsimEventsSchema, fetchForeignAPI, makeEmbed } from '../../../../lib'; +import { Logger, VatsimEventsSchema, fetchForeignAPI, makeEmbed } from '../../../../lib'; const BASE_VATSIM_URL = 'https://my.vatsim.net'; @@ -16,7 +16,7 @@ const handleLocaleDateString = (date: Date) => date.toLocaleDateString('en-US', export async function handleVatsimEvents(interaction: ChatInputCommandInteraction<'cached'>) { try { - const response = await fetchForeignAPI(`${BASE_VATSIM_URL}/api/v1/events/all`, VatsimEventsSchema); + const response = await fetchForeignAPI(`${BASE_VATSIM_URL}/api/v1/events/all`, VatsimEventsSchema); const filteredEvents = response.data.filter((event) => event.type === 'Event'); const finalList = filteredEvents.slice(0, 5); @@ -69,7 +69,7 @@ export async function handleVatsimEvents(interaction: ChatInputCommandInteractio return interaction.editReply({ embeds: [eventsEmbed] }); } catch (e) { - Logger.error(String(e)); + Logger.error(e); const errorEmbed = makeEmbed({ title: 'Events Error', description: String(e), diff --git a/src/commands/utils/vatsim/functions/vatsimPilots.ts b/src/commands/utils/vatsim/functions/vatsimPilots.ts index 31096301..70d9cf1f 100644 --- a/src/commands/utils/vatsim/functions/vatsimPilots.ts +++ b/src/commands/utils/vatsim/functions/vatsimPilots.ts @@ -12,7 +12,7 @@ const listEmbed = (type: string, fields: EmbedField[], totalCount: number, shown description: `A list of ${shownCount} online ${type} matching ${callsign}.`, fields, }); -const pilotsListEmbedFields = (callsign: string, rating?: PilotRating, flightPlan?: FlightPlan) => { +const pilotsListEmbedFields = (callsign: string, flightPlan: FlightPlan | null, rating?: PilotRating) => { const fields = [ { name: 'Callsign', @@ -56,7 +56,7 @@ export async function handleVatsimPilots(interaction: ChatInputCommandInteractio const { callsign, flight_plan } = pilot; const rating = vatsimData.pilot_ratings.find((rating) => rating.id === pilot.pilot_rating); - return pilotsListEmbedFields(callsign, rating, flight_plan ?? undefined); + return pilotsListEmbedFields(callsign, flight_plan, rating); }).splice(0, 5); return interaction.editReply({ embeds: [listEmbed('Pilots', fields.flat(), pilots.length, fields.length, callsignSearch)] }); diff --git a/src/commands/utils/vatsim/vatsim.ts b/src/commands/utils/vatsim/vatsim.ts index bb304d17..d3dfbf66 100644 --- a/src/commands/utils/vatsim/vatsim.ts +++ b/src/commands/utils/vatsim/vatsim.ts @@ -91,13 +91,13 @@ export default slashCommand(data, async ({ interaction }) => { // Fetch VATSIM data let vatsimData: VatsimData; try { - vatsimData = await fetchForeignAPI('https://data.vatsim.net/v3/vatsim-data.json', VatsimDataSchema); + vatsimData = await fetchForeignAPI('https://data.vatsim.net/v3/vatsim-data.json', VatsimDataSchema); } catch (e) { if (e instanceof ZodError) { - e.issues.forEach((issue) => Logger.error(`[zod Issue VATSIM Data] Code: ${issue.code}, Path: ${issue.path.join('.')}, Message: ${issue.message}`)); return interaction.editReply({ embeds: [fetchErrorEmbed('The VATSIM API returned unknown data.')] }); } - return interaction.editReply({ embeds: [fetchErrorEmbed('The VATSIM API returned unknown data.')] }); + Logger.error(`Error while fetching VATSIM data: ${String(e)}.`); + return interaction.editReply({ embeds: [fetchErrorEmbed('An error occurred while fetching data from VATSIM.')] }); } // Grap the callsign from the interaction diff --git a/src/commands/utils/wolframAlpha.ts b/src/commands/utils/wolframAlpha.ts index e8cfcf12..c0dbc686 100644 --- a/src/commands/utils/wolframAlpha.ts +++ b/src/commands/utils/wolframAlpha.ts @@ -23,9 +23,9 @@ const noQueryEmbed = makeEmbed({ color: Colors.Red, }); -const errorEmbed = (errorMessage: string) => makeEmbed({ +const errorEmbed = (error: string) => makeEmbed({ title: 'Wolfram Alpha Error', - description: errorMessage, + description: error, color: Colors.Red, }); @@ -61,7 +61,7 @@ export default slashCommand(data, async ({ interaction }) => { let response: WolframAlphaData; try { - response = await fetchForeignAPI(`${WOLFRAMALPHA_API_URL}${searchParams.toString()}`, WolframAlphaDataSchema); + response = await fetchForeignAPI(`${WOLFRAMALPHA_API_URL}${searchParams.toString()}`, WolframAlphaDataSchema); } catch (e) { if (e instanceof ZodError) { return interaction.editReply({ embeds: [errorEmbed('Wolfram Alpha returned unknown data.')] }); diff --git a/src/lib/apis/fetchForeignAPI.ts b/src/lib/apis/fetchForeignAPI.ts index d26e2e28..8ae1ef8d 100644 --- a/src/lib/apis/fetchForeignAPI.ts +++ b/src/lib/apis/fetchForeignAPI.ts @@ -7,7 +7,7 @@ import { Logger } from '../logger'; * @typeParam ReturnType - The expected type of the returned data. * @param request The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object to be passed to `fetch()`. * @param zodSchema The [Zod](https://github.com/colinhacks/zod) schema that the returned data conforms to. The promise will reject if the returned data does not conform to the schema provided. - * @returns A promise that resolves to the expected type or rejects with an [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error). + * @returns A promise that resolves to the expected type or rejects with an [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) or a {@link ZodError} if the validation failed. */ export const fetchForeignAPI = async (request: RequestInfo, zodSchema: ZodSchema, debug?: boolean): Promise => { const req = new Request(request); @@ -33,10 +33,10 @@ export const fetchForeignAPI = async (request: RequestInfo const result = zodSchema.safeParse(data); if (!result.success) { - Logger.error("[zod] Data validation failed! Pass the 'debug' flag to 'fetchForeignAPI()' to print the retrieved data to the console."); + Logger.error("[zod] Data validation failed! Pass the 'debug' flag to 'fetchForeignAPI()' to dump the retrieved data to the console."); Logger.error(`Endpoint location: ${req.url}.`); if (debug) { - // winston doesn't usefully log object at the moment + // winston doesn't log objects in a useful way at the moment // eslint-disable-next-line no-console console.log('RETRIEVED DATA:', data); } diff --git a/src/lib/apis/zodSchemas/simbrief/simbriefSchemas.ts b/src/lib/apis/zodSchemas/simbrief/simbriefSchemas.ts index 07b71b4a..eb058a25 100644 --- a/src/lib/apis/zodSchemas/simbrief/simbriefSchemas.ts +++ b/src/lib/apis/zodSchemas/simbrief/simbriefSchemas.ts @@ -1,34 +1,34 @@ import { z } from 'zod'; -const FetchSchema = z.object({ status: z.string() }); +const SimBriefFetchSchema = z.object({ status: z.string() }); -const ParamsSchema = z.object({ +const SimBriefParamsSchema = z.object({ user_id: z.string(), time_generated: z.string(), airac: z.string(), }); -const AircraftSchema = z.object({ +const SimBriefAircraftSchema = z.object({ name: z.string(), internal_id: z.string(), }); -const OriginSchema = z.object({ icao_code: z.string() }); +const SimBriefOriginSchema = z.object({ icao_code: z.string() }); -const DestinationSchema = z.object({ icao_code: z.string() }); +const SimBriefDestinationSchema = z.object({ icao_code: z.string() }); -const GeneralSchema = z.object({ route: z.string() }); +const SimBriefGeneralSchema = z.object({ route: z.string() }); /** * This schema only contains currently used fields. If you wish to use other fields returned by the API add them in this file. */ export const SimbriefFlightPlanSchema = z.object({ - fetch: FetchSchema, - params: ParamsSchema, - aircraft: AircraftSchema, - origin: OriginSchema, - destination: DestinationSchema, - general: GeneralSchema, + fetch: SimBriefFetchSchema, + params: SimBriefParamsSchema, + aircraft: SimBriefAircraftSchema, + origin: SimBriefOriginSchema, + destination: SimBriefDestinationSchema, + general: SimBriefGeneralSchema, }); /**