Download src/lib/errors.ts from Jessedbrown/daisy-client: direct link, hf CLI and curl.
- Browser
- Download file 4.38 kB
-
https://huggingface.co/Jessedbrown/daisy-client/resolve/main/src/lib/errors.ts
- Command line
-
hf download hf://Jessedbrown/daisy-client/src/lib/errors.ts
-
curl -L -o errors.ts https://huggingface.co/Jessedbrown/daisy-client/resolve/main/src/lib/errors.ts
4.38 kB
| import { AxiosError } from 'axios'; | |
| import { toast } from 'sonner'; | |
| import { ERROR_CODES, HTTP_STATUS } from '@/utils/constants'; | |
| import { CACHE_CONFIG } from './config'; | |
| export interface AppError { | |
| message: string; | |
| code?: string; | |
| statusCode?: number; | |
| details?: Record<string, unknown>; | |
| } | |
| export class ValidationError extends Error { | |
| constructor( | |
| message: string, | |
| public field?: string | |
| ) { | |
| super(message); | |
| this.name = 'ValidationError'; | |
| } | |
| } | |
| export class NetworkError extends Error { | |
| constructor( | |
| message: string, | |
| public statusCode?: number | |
| ) { | |
| super(message); | |
| this.name = 'NetworkError'; | |
| } | |
| } | |
| export class ApiError extends Error { | |
| constructor( | |
| message: string, | |
| public statusCode?: number, | |
| public code?: string, | |
| public details?: Record<string, unknown> | |
| ) { | |
| super(message); | |
| this.name = 'ApiError'; | |
| } | |
| } | |
| // Error parsing utility | |
| export const parseError = (error: unknown): AppError => { | |
| // Axios error | |
| if (error instanceof AxiosError) { | |
| const statusCode = error.response?.status; | |
| const responseData = error.response?.data as Record<string, unknown>; | |
| const message = | |
| typeof responseData?.message === 'string' | |
| ? responseData.message | |
| : error.message; | |
| const code = | |
| typeof responseData?.code === 'string' ? responseData.code : error.code; | |
| return { | |
| message, | |
| code, | |
| statusCode, | |
| details: responseData?.details as Record<string, unknown>, | |
| }; | |
| } | |
| if (error instanceof ValidationError) { | |
| return { | |
| message: error.message, | |
| code: ERROR_CODES.VALIDATION_ERROR, | |
| details: error.field ? { field: error.field } : undefined, | |
| }; | |
| } | |
| if (error instanceof NetworkError) { | |
| return { | |
| message: error.message, | |
| code: ERROR_CODES.NETWORK_ERROR, | |
| statusCode: error.statusCode, | |
| }; | |
| } | |
| if (error instanceof ApiError) { | |
| return { | |
| message: error.message, | |
| code: error.code ?? ERROR_CODES.API_ERROR, | |
| statusCode: error.statusCode, | |
| details: error.details, | |
| }; | |
| } | |
| if (error instanceof Error) { | |
| return { | |
| message: error.message, | |
| code: ERROR_CODES.UNKNOWN_ERROR, | |
| }; | |
| } | |
| return { | |
| message: 'An unexpected error occurred', | |
| code: ERROR_CODES.UNKNOWN_ERROR, | |
| }; | |
| }; | |
| export const handleMutationError = ( | |
| error: unknown, | |
| defaultMessage = 'Operation failed' | |
| ) => { | |
| const parsedError = parseError(error); | |
| const userMessage = getErrorMessage(error); | |
| toast.error(userMessage || defaultMessage); | |
| console.error('Mutation error:', parsedError); | |
| return parsedError; | |
| }; | |
| export const handleQueryError = (error: unknown, context = 'Loading data') => { | |
| const parsedError = parseError(error); | |
| const userMessage = getErrorMessage(error); | |
| console.error('Query error:', parsedError); | |
| toast.error(`${context} failed: ${userMessage}`); | |
| return parsedError; | |
| }; | |
| export const handleMutationSuccess = (message: string, data?: unknown) => { | |
| toast.success(message); | |
| console.info('Mutation success:', { message, data }); | |
| }; | |
| // Retry logic for network errors | |
| export const shouldRetry = (error: unknown, attemptNumber: number): boolean => { | |
| if (attemptNumber >= CACHE_CONFIG.RETRY.MAX_QUERY_RETRIES) return false; | |
| const parsedError = parseError(error); | |
| // Don't retry client errors (4xx) | |
| if ( | |
| parsedError.statusCode && | |
| parsedError.statusCode >= HTTP_STATUS.BAD_REQUEST && | |
| parsedError.statusCode < HTTP_STATUS.INTERNAL_SERVER_ERROR | |
| ) { | |
| return false; | |
| } | |
| // Retry network errors and server errors (5xx) | |
| return true; | |
| }; | |
| // User-friendly error messages | |
| export const getErrorMessage = (error: unknown): string => { | |
| const parsedError = parseError(error); | |
| switch (parsedError.code) { | |
| case ERROR_CODES.NETWORK_ERROR: | |
| return 'Network connection failed. Please check your internet connection.'; | |
| case ERROR_CODES.VALIDATION_ERROR: | |
| return parsedError.message; | |
| case ERROR_CODES.UNAUTHORIZED: | |
| return 'You are not authorized to perform this action.'; | |
| case ERROR_CODES.FORBIDDEN: | |
| return 'Access denied.'; | |
| case ERROR_CODES.NOT_FOUND: | |
| return 'The requested resource was not found.'; | |
| case ERROR_CODES.RATE_LIMIT: | |
| return 'Too many requests. Please try again later.'; | |
| default: | |
| return parsedError.message || 'An unexpected error occurred'; | |
| } | |
| }; | |