4.8 KiB
4.8 KiB
| name | description |
|---|---|
| production-resilience-observability | Implement production resilience and observability: nested React Error Boundaries, graceful UI degradation, PII-safe telemetry, structured error logging, and retry mechanisms. |
Production Resilience & Observability Architecture
Ce skill empêche l'écran blanc fatal (White Screen of Death). Il impose l'encapsulation modulaire des composants dans des Error Boundaries imbriquées, fournit des interfaces de dégradation gracieuse avec réessai sans rechargement de page, et configure la télémétrie conforme au RGPD (anonymisation stricte des données personnelles dans les logs).
🎯 Déclencheurs d'Activation
Activez ce skill dès que :
- Vous intégrez des composants tiers ou dépendants d'un service distant instable (graphiques, flux en direct, météo, intégrations bancaires).
- Vous structurez l'architecture racine d'une application ou les gabarits de mise en page (Layouts).
- Vous mettez en place la capture d'erreurs en production (Sentry, OpenTelemetry, Datadog).
- Vous configurez des flux de réessai utilisateur en cas d'échec de rendu.
- Vous auditez la protection contre les fuites de données personnelles dans les journaux système (PII Masking).
🛡️ 1. Error Boundaries Imbriquées (Isolation des Pannes)
Une erreur dans une bannière ou un graphique secondaire ne doit jamais casser la barre de navigation ou le tableau de bord principal.
'use client';
import React from 'react';
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
// Interface de repli modulaire avec bouton de réessai ciblé
export const ComponentErrorFallback: React.FC<FallbackProps> = ({ error, resetErrorBoundary }) => {
return (
<div
role="alert"
className="p-5 rounded-xl bg-rose-500/5 border border-rose-500/20 text-start flex flex-col gap-3"
>
<div className="flex items-center gap-2 text-rose-400 font-semibold text-sm">
<span className="size-2 rounded-full bg-rose-400" />
Une erreur temporaire est survenue
</div>
<p className="text-xs text-white/60">
Ce widget n'a pas pu être chargé. Les autres services restent pleinement opérationnels.
</p>
<button
type="button"
onClick={resetErrorBoundary}
className="self-start px-3 py-1.5 rounded-md text-xs font-medium text-white bg-white/10 hover:bg-white/15
border border-white/10 transition-all focus-visible:ring-2 focus-visible:ring-rose-400"
>
Réessayer le chargement
</button>
</div>
);
};
// Encapsulation déclarative
export const SafeWidgetWrapper = ({ children }: { children: React.ReactNode }) => {
return (
<ErrorBoundary
FallbackComponent={ComponentErrorFallback}
onReset={() => {
// Nettoyage ou réinitialisation d'état local si besoin
}}
onError={(error, info) => {
// Journalisation sécurisée
logSafeError(error, info);
}}
>
{children}
</ErrorBoundary>
);
};
🔒 2. Journalisation PII-Safe (Conformité RGPD)
Il est illégal et dangereux d'envoyer des mots de passe, tokens JWT ou adresses email privées dans des outils de tracking de bugs comme Sentry ou Datadog :
// Filtrage et assainissement des données avant expédition
export function logSafeError(error: Error, errorInfo?: any) {
const sanitizedContext = {
message: error.message,
stack: error.stack,
componentStack: errorInfo?.componentStack,
url: window.location.pathname, // Pas de paramètres de requête sensibles (?token=...)
timestamp: new Date().toISOString(),
};
// Masquage des motifs sensibles (regex token/mot de passe/email)
const payloadString = JSON.stringify(sanitizedContext)
.replace(/"(password|token|secret|apiKey)":\s*"[^"]+"/gi, '"$1": "[REDACTED]"')
.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL_REDACTED]');
// Expédition sécurisée vers l'outil d'observabilité
if (process.env.NODE_ENV === 'production') {
// Sentry.captureException(...) ou fetch('/api/telemetry', { body: payloadString })
} else {
console.error('Safe Dev Error Log:', JSON.parse(payloadString));
}
}
📋 Checklist de Conformité Résilience & Observabilité
- Les widgets à risque ou asynchrones sont isolés par leur propre
ErrorBoundary. - Le composant de repli (Fallback) offre un bouton d'action clair pour retenter sans recharger la page entière.
- Aucune donnée personnelle (email, mot de passe, token en URL) n'est envoyée aux outils de télémétrie.
- Le Layout racine possède une frontière d'erreur globale (
global-error.tsxdans Next.js). - Les promesses non interceptées (unhandled rejections) sont écoutées et journalisées proprement.