Files
btpxpress-frontend/components/GlobalErrorHandler.tsx

110 lines
4.2 KiB
TypeScript
Executable File

'use client';
import React, { useEffect, useRef } from 'react';
import { Toast } from 'primereact/toast';
import { apiService } from '../services/api';
interface GlobalErrorHandlerProps {
children?: React.ReactNode;
}
export const GlobalErrorHandler: React.FC<GlobalErrorHandlerProps> = ({ children }) => {
const toast = useRef<Toast>(null);
const lastErrorTime = useRef<number>(0);
useEffect(() => {
// Gestionnaire global d'erreurs non capturées
const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
const error = event.reason;
// Éviter de spammer les notifications (max 1 par seconde)
const now = Date.now();
if (now - lastErrorTime.current < 1000) {
return;
}
lastErrorTime.current = now;
let message = 'Une erreur inattendue s\'est produite';
let severity: 'error' | 'warn' | 'info' = 'error';
if (error?.statusCode === 'NETWORK_ERROR' || error?.statusCode === 'SERVER_UNAVAILABLE') {
message = error.userMessage || 'Serveur indisponible';
severity = 'error';
toast.current?.show({
severity,
summary: 'Serveur backend inaccessible',
detail: message,
sticky: true,
content: (props) => (
<div className="flex flex-column align-items-start" style={{ flex: '1' }}>
<div className="flex align-items-center gap-2">
<i className="pi pi-times-circle text-red-500"></i>
<span className="font-semibold text-900">{props.summary}</span>
</div>
<div className="font-medium text-700 my-2">{message}</div>
<div className="text-600 text-sm">
<div> Démarrez le serveur backend : <code>mvn quarkus:dev</code></div>
<div> Vérifiez que le port 8080 est libre</div>
<div> Contrôlez votre connexion internet</div>
<div> Testez l'accès : <code>http://localhost:8080</code></div>
</div>
</div>
)
});
} else if (error?.statusCode === 'TIMEOUT') {
message = error.userMessage || 'Délai d\'attente dépassé';
severity = 'warn';
toast.current?.show({
severity,
summary: 'Délai dépassé',
detail: message,
life: 6000
});
} else if (error?.userMessage) {
toast.current?.show({
severity: 'error',
summary: 'Erreur',
detail: error.userMessage,
life: 5000
});
}
};
// Gestionnaire de statut serveur
const handleServerStatusChange = (isOnline: boolean) => {
if (isOnline) {
// Nettoyer les messages d'erreur précédents
toast.current?.clear();
toast.current?.show({
severity: 'success',
summary: 'Serveur backend reconnecté',
detail: 'Le serveur backend est de nouveau accessible',
life: 3000
});
}
};
// Enregistrer les listeners
window.addEventListener('unhandledrejection', handleUnhandledRejection);
const unsubscribe = apiService.onServerStatusChange(handleServerStatusChange);
return () => {
window.removeEventListener('unhandledrejection', handleUnhandledRejection);
if (unsubscribe) {
unsubscribe();
}
};
}, []);
return (
<>
<Toast ref={toast} position="top-right" />
{children}
</>
);
};
export default GlobalErrorHandler;