diff --git a/apps/drive-web/src/lib/error.ts b/apps/drive-web/src/lib/error.ts index 4e3590b..0cf5564 100644 --- a/apps/drive-web/src/lib/error.ts +++ b/apps/drive-web/src/lib/error.ts @@ -1,7 +1,9 @@ import { - Code as ErrorCode, + type ApplicationErrorData, + ErrorCode, isApplicationError, } from "@fileone/convex/error" +import { ConvexError } from "convex/values" import { toast } from "sonner" const ERROR_MESSAGE = { @@ -9,13 +11,19 @@ const ERROR_MESSAGE = { [ErrorCode.FileExists]: "File already exists", [ErrorCode.Internal]: "Internal application error", [ErrorCode.Conflict]: "Conflict", - [ErrorCode.DirectoryNotFound]: "Directory not found", - [ErrorCode.FileNotFound]: "File not found", [ErrorCode.Unauthenticated]: "Unauthenticated", + [ErrorCode.NotFound]: "Not found", + [ErrorCode.StorageQuotaExceeded]: "Storage is full", } as const +export function isApplicationConvexError( + error: unknown, +): error is ConvexError { + return error instanceof ConvexError && isApplicationError(error.data) +} + export function formatError(error: unknown): string { - if (isApplicationError(error)) { + if (isApplicationConvexError(error)) { return ERROR_MESSAGE[error.data.code] } if (error instanceof Error) { @@ -25,8 +33,12 @@ export function formatError(error: unknown): string { } export function defaultOnError(error: unknown) { - console.log(error) - toast.error(formatError(error)) + if (isApplicationConvexError(error)) { + toast.error(formatError(error)) + } else { + console.error("Catastrophic error:", error) + toast.error("An unexpected error occurred") + } } export function withDefaultOnError(fn: (error: unknown) => void) { diff --git a/apps/drive-web/vite.config.ts b/apps/drive-web/vite.config.ts index b9fcc6c..313dc18 100644 --- a/apps/drive-web/vite.config.ts +++ b/apps/drive-web/vite.config.ts @@ -1,7 +1,7 @@ +import path from "node:path" import tailwindcss from "@tailwindcss/vite" import { TanStackRouterVite } from "@tanstack/router-plugin/vite" import react from "@vitejs/plugin-react" -import path from "path" import { defineConfig } from "vite" export default defineConfig({ @@ -19,7 +19,7 @@ export default defineConfig({ }, }, optimizeDeps: { - include: ["convex/react", "convex-helpers"], + include: ["convex/react", "convex/values", "convex-helpers"], // Workaround for better-auth bug: https://github.com/better-auth/better-auth/issues/4457 // Vite's esbuild incorrectly transpiles better-call dependency causing 'super' keyword errors exclude: ["better-auth", "@convex-dev/better-auth"], diff --git a/packages/convex/shared/error.ts b/packages/convex/shared/error.ts index 5c49098..f33379e 100644 --- a/packages/convex/shared/error.ts +++ b/packages/convex/shared/error.ts @@ -1,36 +1,44 @@ import { ConvexError } from "convex/values" -export enum Code { +export enum ErrorCode { Conflict = "Conflict", DirectoryExists = "DirectoryExists", - DirectoryNotFound = "DirectoryNotFound", FileExists = "FileExists", - FileNotFound = "FileNotFound", Internal = "Internal", Unauthenticated = "Unauthenticated", NotFound = "NotFound", StorageQuotaExceeded = "StorageQuotaExceeded", } -export type ApplicationErrorData = { code: Code; message?: string } -export type ApplicationError = ConvexError +export type ApplicationErrorData = { code: ErrorCode; message?: string } -export function isApplicationError(error: unknown): error is ApplicationError { - return error instanceof ConvexError && "code" in error.data +export function isApplicationError( + error: unknown, +): error is ApplicationErrorData { + return ( + error !== null && + typeof error === "object" && + "code" in error && + "message" in error && + Object.values(ErrorCode).includes( + (error as { code: string }).code as ErrorCode, + ) + ) } -export function create(code: Code, message?: string): ApplicationError { - return new ConvexError({ - code, - message: - code === Code.Internal ? "Internal application error" : message, - }) -} - -export function createJson(code: Code, message?: string): ApplicationErrorData { +export function createErrorData( + code: ErrorCode, + message?: string, +): ApplicationErrorData { return { code, message: - code === Code.Internal ? "Internal application error" : message, + code === ErrorCode.Internal + ? "Internal application error" + : message, } } + +export function error(data: ApplicationErrorData): never { + throw new ConvexError(data) +}