From 5eb7bc18b8f96ad7095e8e3df641717511b6ba02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Fri, 10 Nov 2023 15:45:07 +0200 Subject: [PATCH] @thunderstore/dapper-ts: improve error handling Sentry handling doesn't need to be done on package level since we're doing it on app level. Try to throw useful error messages, taking into account I don't how much of the error stack is available on Sentry or NextJs logs this way. Refs no ticket --- packages/dapper-ts/src/methods/communities.ts | 7 +++---- packages/dapper-ts/src/methods/communityFilters.ts | 4 ++-- packages/dapper-ts/src/methods/currentUser.ts | 4 ++-- packages/dapper-ts/src/methods/packageListings.ts | 4 ++-- packages/dapper-ts/src/methods/team.ts | 7 +++---- packages/dapper-ts/src/utils.ts | 13 +++++++++++++ 6 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 packages/dapper-ts/src/utils.ts diff --git a/packages/dapper-ts/src/methods/communities.ts b/packages/dapper-ts/src/methods/communities.ts index 4b356c4d0..eda53c076 100644 --- a/packages/dapper-ts/src/methods/communities.ts +++ b/packages/dapper-ts/src/methods/communities.ts @@ -6,6 +6,7 @@ import { import { DapperTsInterface } from "../index"; import { paginatedResults } from "../sharedSchemas"; +import { formatErrorMessage } from "../utils"; const communitySchema = z.object({ name: z.string().nonempty(), @@ -31,8 +32,7 @@ export async function getCommunities( const parsed = communitiesSchema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return { @@ -50,8 +50,7 @@ export async function getCommunity( const parsed = communitySchema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return parsed.data; diff --git a/packages/dapper-ts/src/methods/communityFilters.ts b/packages/dapper-ts/src/methods/communityFilters.ts index 2973a591a..d1d40262b 100644 --- a/packages/dapper-ts/src/methods/communityFilters.ts +++ b/packages/dapper-ts/src/methods/communityFilters.ts @@ -3,6 +3,7 @@ import { fetchCommunityFilters } from "@thunderstore/thunderstore-api"; import { DapperTsInterface } from "../index"; import { PackageCategory } from "../sharedSchemas"; +import { formatErrorMessage } from "../utils"; const Section = z.object({ uuid: z.string().uuid(), @@ -24,8 +25,7 @@ export async function getCommunityFilters( const parsed = schema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return parsed.data; diff --git a/packages/dapper-ts/src/methods/currentUser.ts b/packages/dapper-ts/src/methods/currentUser.ts index e7f251ae7..e7dd99804 100644 --- a/packages/dapper-ts/src/methods/currentUser.ts +++ b/packages/dapper-ts/src/methods/currentUser.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { fetchCurrentUser } from "@thunderstore/thunderstore-api"; import { DapperTsInterface } from "../index"; +import { formatErrorMessage } from "../utils"; const oAuthConnectionSchema = z.object({ provider: z.string().nonempty(), @@ -42,8 +43,7 @@ export async function getCurrentUser(this: DapperTsInterface) { const parsed = schema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } // For legacy support, the backend returns teams in two formats. diff --git a/packages/dapper-ts/src/methods/packageListings.ts b/packages/dapper-ts/src/methods/packageListings.ts index fd19597e8..f6a105a0c 100644 --- a/packages/dapper-ts/src/methods/packageListings.ts +++ b/packages/dapper-ts/src/methods/packageListings.ts @@ -8,6 +8,7 @@ import { PackageListingQueryParams } from "@thunderstore/thunderstore-api/types" import { DapperTsInterface } from "../index"; import { PackageCategory, paginatedResults } from "../sharedSchemas"; +import { formatErrorMessage } from "../utils"; const packageListingSchema = z.object({ categories: PackageCategory.array(), @@ -73,8 +74,7 @@ export async function getPackageListings( const parsed = schema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return { diff --git a/packages/dapper-ts/src/methods/team.ts b/packages/dapper-ts/src/methods/team.ts index 929b6fdc9..302188134 100644 --- a/packages/dapper-ts/src/methods/team.ts +++ b/packages/dapper-ts/src/methods/team.ts @@ -6,6 +6,7 @@ import { } from "@thunderstore/thunderstore-api"; import { DapperTsInterface } from "../index"; +import { formatErrorMessage } from "../utils"; const detailsSchema = z.object({ identifier: z.number().int().gt(0), @@ -45,8 +46,7 @@ export async function getTeamMembers( const parsed = membersSchema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return parsed.data; @@ -68,8 +68,7 @@ export async function getTeamServiceAccounts( const parsed = serviceAccountSchema.safeParse(data); if (!parsed.success) { - // TODO: add Sentry support and log parsed.error. - throw new Error("Invalid data received from backend"); + throw new Error(formatErrorMessage(parsed.error)); } return parsed.data; diff --git a/packages/dapper-ts/src/utils.ts b/packages/dapper-ts/src/utils.ts new file mode 100644 index 000000000..352d88773 --- /dev/null +++ b/packages/dapper-ts/src/utils.ts @@ -0,0 +1,13 @@ +import { ZodError } from "zod"; + +export const formatErrorMessage = (errors: ZodError) => { + const issues = errors.issues.map( + (issue) => ` ${issue.path.join(".")}: ${issue.message}` + ); + + issues.unshift( + `Invalid data received from backend (${errors.issues.length}):` + ); + + return issues.join("\n"); +};