Files
thrilltrack-explorer/lib/api/errorHandler.ts

94 lines
1.9 KiB
TypeScript

import { AxiosError } from 'axios';
export interface ApiError {
message: string;
code?: string;
status: number;
details?: Record<string, string[]>;
}
export function handleApiError(error: unknown): ApiError {
if (error instanceof AxiosError) {
const status = error.response?.status || 500;
const data = error.response?.data;
// Django validation errors
if (status === 400 && data) {
return {
message: 'Validation failed',
code: 'VALIDATION_ERROR',
status,
details: data,
};
}
// Authentication errors
if (status === 401) {
return {
message: 'Authentication required',
code: 'UNAUTHORIZED',
status,
};
}
// Permission errors
if (status === 403) {
return {
message: 'Permission denied',
code: 'FORBIDDEN',
status,
};
}
// Not found
if (status === 404) {
return {
message: 'Resource not found',
code: 'NOT_FOUND',
status,
};
}
// Rate limiting
if (status === 429) {
return {
message: 'Too many requests',
code: 'RATE_LIMITED',
status,
};
}
// Server errors
if (status >= 500) {
return {
message: 'Server error occurred',
code: 'SERVER_ERROR',
status,
};
}
return {
message: data?.message || error.message || 'An error occurred',
code: 'API_ERROR',
status,
};
}
// Network errors
return {
message: 'Network error occurred',
code: 'NETWORK_ERROR',
status: 0,
};
}
export function formatErrorForUser(error: ApiError): string {
if (error.details) {
const messages = Object.entries(error.details)
.map(([field, errors]) => `${field}: ${errors.join(', ')}`)
.join('\n');
return messages;
}
return error.message;
}