thekof
Tous les articles
{"API","HTTP","Debug","Status Code","Frontend","Backend"}01/01/200012 min

Debug API par status code : 400, 403, 404, 413, 500 et le reste

Un seul guide pour debugger les erreurs HTTP (400, 403, 404, 413, 500…) : lire la famille du code, le détail exact, et chercher au bon endroit dès le départ.

Debug API par status code : 400, 403, 404, 413, 500 et le reste

Introduction

T'as cliqué sur un bouton. La donnée n'apparaît pas. Tu ouvres la console. Tu vois une erreur rouge. Et là, le réflexe classique :

  1. Tu changes le composant frontend
  2. Tu testes un autre endpoint
  3. Tu regénères ton token
  4. Tu demandes à une IA
  5. Tu passes 45 minutes à chercher

...alors que le status code HTTP te donnait la réponse depuis le début.

403 ne veut pas dire token invalide. Ça veut dire tu es connecté, mais tu n'as pas la permission. Ce n'est pas pareil. Et cette différence peut te faire perdre une heure.

Ce guide te donne une méthode simple : lire la famille du code en premier, le code exact ensuite, et debugger dans le bon sens dès le départ.


La méthode : famille d'abord, détail ensuite

Un status code HTTP se lit comme une adresse. La centaine te donne le quartier. Le chiffre exact te donne la porte.

2xx → succès 3xx → redirection ou cache 4xx → problème côté requête client 5xx → problème côté serveur ou infrastructure

Si tu retiens seulement ces quatre lignes, tu debugges déjà plus proprement que la majorité.


Codes 2xx — La requête a réussi

Quand tu vois un 2xx, l'API a bien reçu et traité ta requête. Le bug est ailleurs — probablement dans ce que ton code fait avec la réponse.


200 OK

La requête a réussi. Une réponse est disponible.

Ce que ça signifie : Le serveur a compris, exécuté, et retourné une réponse. Si quelque chose ne s'affiche pas, le bug est dans ta logique après la réponse.

À vérifier :

  • La vraie forme du JSON reçu
  • Les noms exacts des propriétés
  • Les tableaux vides traités comme des erreurs
  • Les valeurs null non gérées
  • Une condition d'affichage incorrecte

Exemple de piège classique :

js
// L'API retourne { data: { user: { name: "Elton" } } } // Mais ton code fait : const name = response.name // undefined // Alors que c'est : const name = response.data.user.name // ✅

201 Created

Une ressource vient d'être créée côté serveur.

Ce que ça signifie : Ton POST a fonctionné. L'objet existe maintenant. Tu dois souvent récupérer son id et synchroniser ton état local.

À vérifier :

  • L'id ou l'objet retourné dans le body
  • La mise à jour du state local
  • L'affichage du message de confirmation côté UI

Exemple :

js
const response = await fetch("/api/posts", { method: "POST", body: JSON.stringify({ title: "Mon article" }) }) if (response.status === 201) { const newPost = await response.json() // ✅ Ajoute le nouvel objet dans ton state setPosts(prev => [...prev, newPost]) }

204 No Content

L'action a réussi, mais le serveur ne renvoie rien.

Ce que ça signifie : Succès silencieux. Souvent utilisé pour DELETE ou certaines actions simples. Il n'y a pas de body à parser.

Erreur typique :

js
// ❌ Ça plantera — response.json() sur un body vide const data = await response.json() // ✅ Vérifie le status avant de parser if (response.status !== 204) { const data = await response.json() }

Codes 3xx — Redirection ou cache

Quand tu vois un 3xx, le serveur t'indique que la ressource a bougé, ou que tu peux utiliser une version en cache.


301 Moved Permanently

L'URL a changé définitivement.

À faire : Mets à jour l'endpoint dans tes variables d'environnement. L'ancienne adresse ne reviendra plus.


302 Found

Redirection temporaire.

À faire : Vérifie si ton client HTTP suit les redirects automatiquement. Inspecte le header Location pour voir la destination.


304 Not Modified

La ressource n'a pas changé depuis la dernière fois.

À faire : Le serveur te dit d'utiliser ta version en cache. Si tu vois des données obsolètes, inspecte tes headers Cache-Control et ETag.


Codes 4xx — Le problème vient de ta requête

C'est la famille la plus importante à maîtriser. Quand tu vois un 4xx, ne cherche pas du côté serveur. Inspecte ce que ton client envoie.


400 Bad Request

Ta requête est invalide. Le serveur comprend l'endpoint, mais pas ce que tu lui envoies.

Causes fréquentes :

  • JSON mal formé
  • Champ obligatoire absent
  • Mauvais type de données
  • Format de date invalide
  • body envoyé alors que l'API attend des query params

Checklist :

http
POST /api/projects HTTP/1.1 Content-Type: application/json ← est-ce correct ? { "projectName": "AfriCreator" ← l'API attend peut-être "name" ? }

Exemple de diagnostic :

L'API répond 400. Le body d'erreur dit : "Field 'name' is required." Mon code envoie 'projectName'. → Je dois renommer le champ en 'name'.


401 Unauthorized

Le serveur ne reconnaît pas ton identité.

Causes fréquentes :

  • Token absent
  • Token expiré
  • Token invalide ou mal formé
  • Mauvais format du header d'autorisation
  • Mauvais environnement (tu utilises un token de staging en prod)

À vérifier :

http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
  • Le mot Bearer est-il présent ?
  • Le token est-il encore valide ?
  • Le token vient-il du bon environnement ?

Différence clé :

401 → "Je ne sais pas qui tu es." 403 → "Je sais qui tu es, mais t'as pas le droit."


403 Forbidden

Tu es reconnu, mais l'accès est refusé.

Causes fréquentes :

  • Rôle insuffisant (user au lieu d'admin)
  • Scope du token trop limité
  • Ressource appartenant à un autre utilisateur
  • Fonctionnalité non incluse dans le plan actuel

Piège classique :

js
// Tu vois 403 → tu penses "token invalide" // Tu regénères un token → 403 encore // Parce que le problème n'est PAS le token // C'est que l'utilisateur n'a pas la permission d'accéder à cette route // ✅ Vérifie le rôle de l'utilisateur, pas son token

404 Not Found

La ressource est introuvable.

Causes fréquentes :

  • Endpoint incorrect
  • ID inexistant ou supprimé
  • Mauvaise version d'API (/v1 au lieu de /v2)
  • Mauvaise méthode HTTP

Exemple de diagnostic :

js
// Tu appelles : fetch("https://api.africreator.app/v1/posts/999") // → 404 // Vérifie : // 1. L'ID 999 existe-t-il en base ? // 2. La version /v1 est-elle la bonne ? // 3. La méthode est-elle GET ? // 4. L'environnement est-il le bon (local vs prod) ?

Cas classique en frontend :

Tout marche en local → 404 en production → Comparer les variables d'environnement → Souvent une URL de base ou un préfixe de route différent


413 Payload Too Large

La requête est trop lourde pour le serveur.

Causes fréquentes :

  • Upload de fichier trop volumineux
  • Body JSON énorme (base64 d'image inline, etc.)
  • Limite nginx / API Gateway trop basse

À vérifier :

  • Taille réelle du payload
  • Compression ou upload multipart
  • Limites client_max_body_size / config cloud

429 Too Many Requests

Tu envoies trop de requêtes. Le serveur te rate-limite.

Causes fréquentes :

  • Boucle de requêtes
  • useEffect qui se déclenche à chaque rendu
  • Recherche sans debounce
  • Retry automatique agressif

Exemple :

js
// ❌ Chaque frappe envoie une requête API <input onChange={(e) => fetchResults(e.target.value)} /> // ✅ Avec debounce — attend 300ms d'inactivité const debouncedFetch = useMemo( () => debounce(fetchResults, 300), [] ) <input onChange={(e) => debouncedFetch(e.target.value)} />

Lis aussi le header Retry-After — il t'indique combien de secondes attendre avant de réessayer.


Codes 5xx — Le problème vient du serveur

Quand tu vois un 5xx, la requête est arrivée côté serveur, mais quelque chose a cassé là-bas. Ce n'est pas (forcément) ton code frontend.


500 Internal Server Error

Le serveur a rencontré une erreur inattendue.

Causes fréquentes :

  • Exception non gérée dans le backend
  • Variable d'environnement absente
  • Données inattendues qui font crasher un traitement
  • Problème de base de données

À faire :

  • Lire les logs backend
  • Reproduire la requête avec un client API comme Postman ou Insomnia
  • Logger le payload exact reçu par le serveur

502 Bad Gateway

Un intermédiaire (proxy, load balancer) n'obtient pas une réponse valide de ta backend.

Causes fréquentes :

  • Backend down
  • Service upstream indisponible
  • Mauvaise configuration du reverse proxy
  • Déploiement instable

À faire : Vérifie la santé du service cible. Regarde les logs de ton infrastructure (Nginx, Vercel, Railway, etc.).


503 Service Unavailable

Le service n'est pas disponible pour l'instant.

Causes fréquentes :

  • Maintenance en cours
  • Surcharge
  • Déploiement en cours

À faire : Vérifie la page de statut du service. Prévois un message utilisateur propre côté frontend au lieu d'afficher l'erreur brute.


504 Gateway Timeout

Un serveur intermédiaire attendait une réponse, mais elle n'est pas arrivée à temps.

Causes fréquentes :

  • Requête SQL trop lente
  • API externe lente
  • Traitement synchrone trop long

Exemple :

js
// L'utilisateur déclenche une action // Le backend appelle une API tierce // L'API tierce met 35 secondes à répondre // Le gateway timeout est à 30 secondes // → 504 // Solution : passer le traitement en tâche asynchrone (queue) // Et retourner immédiatement un 202 Accepted

Matrice de décision rapide

CodeCe que ça veut direPremier réflexe
200SuccèsVérifier la logique après réponse
201Ressource crééeRécupérer l'ID, synchroniser le state
204Succès sans contenuNe pas parser de body
301URL déplacée définitivementMettre à jour l'endpoint
302Redirection temporaireInspecter le header Location
304Pas de changementVérifier le cache
400Requête invalideInspecter body, params et types
401Non authentifiéVérifier token et header auth
403Non autoriséVérifier rôle, permission et scope
404IntrouvableVérifier URL, ID, route, environnement
429Trop de requêtesAjouter debounce, cache ou backoff
500Erreur serveurLire les logs backend
502Upstream défaillantVérifier gateway, proxy, service amont
503Service indisponibleVérifier surcharge ou maintenance
504TimeoutIdentifier l'appel trop lent

Workflow complet de debug

Quand tu tombes sur une erreur API, suis cet ordre. Pas l'inverse.

Étape 1 — Capture la vraie requête

Ne te fie pas à ce que tu crois envoyer. Vérifie ce qui part réellement :

✓ URL complète (avec le bon domaine et la bonne version) ✓ Méthode HTTP (GET, POST, PUT, PATCH, DELETE) ✓ Headers (Authorization, Content-Type...) ✓ Body (format, noms des champs, types) ✓ Query params ✓ Environnement (local, staging, prod)

Étape 2 — Lis la famille du status code

2xx ? → Succès. Cherche dans ta logique post-réponse. 3xx ? → Redirection ou cache. Vérifie URL et headers. 4xx ? → Problème client. Inspecte ta requête. 5xx ? → Problème serveur. Regarde les logs.

Étape 3 — Lis le body d'erreur complet

Le code ne suffit pas. L'API envoie souvent un message précis :

json
{ "error": "Validation failed", "details": [ { "field": "email", "message": "Invalid email format" } ] }

Ce message est souvent plus utile que le code.

Étape 4 — Reproduis hors du frontend

Utilise Postman, Insomnia, ou curl pour isoler le problème :

bash
curl -X POST https://api.africreator.app/v1/posts \ -H "Authorization: Bearer <ton_token>" \ -H "Content-Type: application/json" \ -d '{"title": "Mon post", "content": "..."}'

Si ça marche ici → le bug est dans ton frontend. Si ça échoue ici → le bug est dans la requête ou l'API.

Étape 5 — Change une seule chose à la fois

Si tu modifies le token, l'URL, le body et un composant en même temps, tu ne sauras jamais ce qui a corrigé le problème.


Exemples de diagnostic complets

Exemple 1 — Le bouton supprimer semble marcher, mais l'élément revient

Symptôme : clic → l'élément disparaît → réapparaît après Status code : 204 No Content Diagnostic : la suppression côté API réussit. Le bug est dans la synchronisation du state local. Solution : filtrer l'élément supprimé dans le state immédiatement.

js
// ✅ Supprimer localement après confirmation API if (response.status === 204) { setItems(prev => prev.filter(item => item.id !== deletedId)) }

Exemple 2 — L'admin ne peut pas accéder à une route protégée

Symptôme : clic sur "Accès admin" → erreur Status code : 403 Forbidden Réflexe faux : regénérer le token Bon réflexe : vérifier le rôle de l'utilisateur dans la BDD Découverte : le compte a été créé comme "user", pas "admin" Solution : mettre à jour le rôle côté base de données


Exemple 3 — La recherche plante après quelques frappes

Symptôme : l'utilisateur tape → erreur après 3-4 mots Status code : 429 Too Many Requests Diagnostic : une requête envoyée à chaque keystroke Solution : ajouter un debounce de 300ms


Exemple 4 — Tout marche en local, rien en production

Symptôme : fonctionnel en local, 404 en prod Status code : 404 Not Found Hypothèses à tester :

  1. Variable VITE_API_URL différente entre .env et .env.production
  2. Préfixe /v1 manquant en production
  3. Route non déployée côté backend Découverte : VITE_API_URL pointe sur localhost en prod (oubli de config)

Le mémo à garder

Colle ça dans ton espace de travail :

Debug API — Famille d'abord

2xx → succès → vérifier la logique après réponse 3xx → redirection/cache → vérifier URL et headers 4xx → problème client → inspecter requête, auth, permissions 5xx → problème serveur → vérifier logs, infra, dépendances

400 → corps de requête invalide 401 → non authentifié (token) 403 → non autorisé (permission/rôle) 404 → ressource introuvable (URL, ID, env) 429 → trop de requêtes (debounce) 500 → crash backend (logs) 504 → timeout (appel trop lent)


Conclusion

Un status code HTTP n'est pas juste une erreur dans la console.

C'est un signal. Une direction. Un raccourci de diagnostic.

L'API t'a déjà dit ce qui cloche.

Il te reste à apprendre à la lire.

The KOF 👌

À lire ensuite