85 lines
2.0 KiB
TypeScript
85 lines
2.0 KiB
TypeScript
/**
|
|
* 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
|
|
* <script lang="ts">
|
|
* import { handleApiError } from '$lib/utils/error-handler';
|
|
* let { data } = $props();
|
|
*
|
|
* $effect(() => {
|
|
* handleApiError(data.error);
|
|
* });
|
|
* </script>
|
|
* ```
|
|
*/
|
|
export function useErrorHandler(error?: ApiError | null) {
|
|
if (error) {
|
|
handleApiError(error);
|
|
}
|
|
}
|