/** * Utilidades para manejar errores de API en el cliente */ import { toast } from 'svelte-sonner'; export interface ApiError { detail: string; status: number; isForbidden?: boolean; } /** * Maneja errores de API mostrando el toast apropiado * @param error - El error a manejar (puede ser un objeto ApiError o un string) * @returns true si se manejó un error, false si no había error */ export function handleApiError(error?: ApiError | string | null): boolean { if (!error) return false; // Si es un string, convertirlo a objeto if (typeof error === 'string') { // Detectar si es un error 403 if (error.includes('403') || error.toLowerCase().includes('forbidden')) { toast.error(error, { duration: 5000, description: 'No tienes permisos para realizar esta acción' }); return true; } // Otros errores en formato string toast.error(error, { duration: 4000 }); return true; } // Es un objeto ApiError if (error.isForbidden || error.status === 403) { // Mostrar el mensaje específico del backend si está disponible const message = error.detail || 'No tienes permisos para realizar esta acción'; toast.error(message, { duration: 5000, description: error.detail ? 'Contacta a tu administrador si crees que esto es un error' : undefined }); return true; } if (error.status === 401) { toast.error('Sesión expirada', { duration: 3000, description: 'Por favor, inicia sesión nuevamente' }); return true; } // Otros errores toast.error(error.detail || 'Error en la operación', { duration: 4000 }); return true; } /** * Hook para usar en componentes Svelte con $effect * Muestra automáticamente un toast cuando hay un error * * Ejemplo de uso en +page.svelte: * ```svelte * * ``` */ export function useErrorHandler(error?: ApiError | null) { if (error) { handleApiError(error); } }