Gestion d'erreurs 2xx/3xx/4xx/5xx : la matrice qui couvre tout
90% des SaaS gèrent 200 et 500. Les 4xx (validation, auth, rate limit) tombent dans un catch générique → mauvais UX, bugs invisibles.
La matrice obligatoire
| Code | Cas | Action client |
|---|---|---|
| 200 | Succès | Toast succès + update UI optimiste |
| 201 | Créé | Toast + redirect vers la ressource |
| 204 | No content | Update UI sans payload |
| 301/302 | Redirect | Suivre (fetch natif le fait) |
| 304 | Not modified | Servir le cache |
| 400 | Validation | Toast erreur champ par champ |
| 401 | Non auth | Redirect /login + save returnUrl |
| 403 | Interdit | Toast "permission refusée" |
| 404 | Introuvable | Composant NotFound dédié |
| 409 | Conflit (doublon) | Toast spécifique "déjà existant" |
| 422 | Validation serveur | Map des erreurs vers form fields |
| 429 | Rate limit | Toast + countdown retry |
| 500 | Erreur serveur | Toast + Sentry + bouton retry |
| 502/503/504 | Gateway/down | Toast "réessayez dans X" |
Le pattern `ApiError` typé partagé
Une seule classe côté edge function ApiError(status, code, message, details?). Un seul handler côté client handleApiError(error) qui mappe code → toast + action. Plus jamais de alert("Erreur").
Anti-pattern : try/catch silencieux
try { ... } catch (e) { console.log(e) } = bug invisible en prod. Règle : toute exception non-gérée doit remonter à un boundary (ErrorBoundary React + Sentry). Pas de catch sans action.
Partager