110 lines
4.2 KiB
TypeScript
Executable File
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; |