Aller au contenu principal
Guides Techniques 7 min de lecture

Gestion des erreurs WhatsApp API : codes d'erreur, retry logic et bonnes pratiques

Maîtrisez la gestion des erreurs de l'API WhatsApp Business Cloud. Codes d'erreur courants, implémentation du retry logic, et bonnes pratiques pour une intégration robuste.

Gestion des erreurs WhatsApp API : codes d'erreur, retry logic et bonnes pratiques

Une intégration WhatsApp API qui fonctionne parfaitement en conditions idéales n'est pas une intégration robuste. Les erreurs sont inévitables : réseau instable, token expiré, numéro invalide, limite de débit dépassée. En Afrique, ces problèmes sont encore plus fréquents : la connectivité mobile peut être intermittente, les numéros changent souvent, et les pics de trafic lors de promotions peuvent surcharger momentanément les API. Savoir gérer ces erreurs proprement, c'est la différence entre un système qui se dégrade gracieusement et un système qui perd silencieusement des messages critiques.

Anatomie d'une erreur WhatsApp API

Quand l'API retourne une erreur, le corps de la réponse JSON suit toujours cette structure :

{
  "error": {
    "message": "Invalid phone number",
    "type": "OAuthException",
    "code": 100,
    "error_data": {
      "messaging_product": "whatsapp",
      "details": "The phone number +221700000000 is not valid"
    },
    "error_subcode": 2494010,
    "fbtrace_id": "AbcDef123456"
  }
}

Les champs essentiels sont code (code d'erreur principal), error_subcode (détail précis de l'erreur), message (description lisible) et fbtrace_id (identifiant unique pour le support Meta). Gardez toujours le fbtrace_id dans vos logs : c'est indispensable si vous ouvrez un ticket de support.

Les codes d'erreur les plus courants

Voici les erreurs que vous rencontrerez fréquemment :

Erreurs d'authentification et d'autorisation :

  • 190 — Token d'accès expiré ou invalide. Solution : renouveler le token.
  • 200 — Permission manquante. Vérifiez les scopes de votre application.
  • 10 — Permission refusée. Votre compte n'a pas accès à cette fonctionnalité.

Erreurs de destinataire :

  • 131030 — Numéro de téléphone non valide ou non enregistré sur WhatsApp.
  • 131031 — Le destinataire a bloqué votre numéro.
  • 131047 — Message non autorisé : plus de 24h sans réponse client, utilisez un template.
  • 131026 — Le message n'a pas pu être livré (numéro injoignable, stockage plein).

Erreurs de rate limiting :

  • 130429 — Rate limit atteint. Réduisez la fréquence d'envoi.
  • 131048 — Limite de spam atteinte. Votre numéro a été temporairement restreint.

Erreurs de template :

  • 132000 — Template introuvable ou non approuvé.
  • 132001 — Template rejeté ou désactivé par Meta.
  • 132007 — Paramètres du template incorrects (mauvais nombre ou type).

Erreurs de média :

  • 131053 — URL du média inaccessible ou invalide.
  • 131054 — Taille du fichier dépassée.

Implémentation du retry logic

La stratégie de retry doit être différente selon le type d'erreur. Certaines erreurs sont définitives (numéro invalide) et ne méritent pas de retry. D'autres sont temporaires (rate limit, erreur serveur) et nécessitent une attente avant relance.

// Node.js - Retry avec backoff exponentiel
class WhatsAppAPIError extends Error {
    constructor(code, message, subcode, fbtrace) {
        super(message);
        this.code = code;
        this.subcode = subcode;
        this.fbtrace = fbtrace;
        this.retryable = this.isRetryable(code);
    }
    
    isRetryable(code) {
        // Erreurs temporaires : à retenter
        const retryableCodes = [
            429,    // HTTP Too Many Requests
            500,    // Internal Server Error
            502,    // Bad Gateway
            503,    // Service Unavailable
            130429, // WhatsApp rate limit
        ];
        return retryableCodes.includes(code);
    }
}

async function sendWithRetry(payload, maxAttempts = 5) {
    let attempt = 0;
    
    while (attempt < maxAttempts) {
        try {
            const response = await axios.post(API_URL, payload, { headers: HEADERS });
            return response.data;
            
        } catch (error) {
            attempt++;
            const apiError = parseApiError(error);
            
            // Ne pas retenter les erreurs définitives
            if (!apiError.retryable) {
                console.error(`Erreur définitive [${apiError.code}]: ${apiError.message}`);
                throw apiError;
            }
            
            if (attempt >= maxAttempts) {
                console.error(`Échec après ${maxAttempts} tentatives`);
                throw apiError;
            }
            
            // Backoff exponentiel avec jitter
            const baseDelay = 1000; // 1 seconde
            const delay = Math.min(baseDelay * Math.pow(2, attempt) + Math.random() * 1000, 60000);
            console.log(`Tentative ${attempt}/${maxAttempts}, attente ${delay}ms...`);
            await sleep(delay);
        }
    }
}

function parseApiError(axiosError) {
    const data = axiosError.response?.data?.error || {};
    const httpCode = axiosError.response?.status || 0;
    const code = data.code || httpCode;
    
    return new WhatsAppAPIError(
        code,
        data.message || axiosError.message,
        data.error_subcode,
        data.fbtrace_id
    );
}

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

Pour les erreurs de rate limit (code 130429), respectez le header Retry-After si présent dans la réponse HTTP :

async function handleRateLimitError(error) {
    const retryAfter = parseInt(error.response?.headers['retry-after'] || '60');
    console.log(`Rate limit atteint. Attente de ${retryAfter} secondes...`);
    await sleep(retryAfter * 1000);
}

Gestion avancée des erreurs en production

En production, une bonne gestion des erreurs implique plusieurs niveaux :

Classification des erreurs :

function classifyError(code) {
    const classifications = {
        // Erreurs d'entrée - corriger les données
        'invalid_input': [131030, 132007, 100],
        // Erreurs de permission - vérifier configuration  
        'permission': [190, 200, 10],
        // Erreurs temporaires - retenter
        'transient': [130429, 500, 502, 503],
        // Erreurs de logique métier - changer l'approche
        'business_logic': [131047, 131031, 131048]
    };
    
    for (const [category, codes] of Object.entries(classifications)) {
        if (codes.includes(code)) return category;
    }
    return 'unknown';
}

async function handleMessageError(messageId, recipientPhone, error) {
    const category = classifyError(error.code);
    
    switch(category) {
        case 'invalid_input':
            // Marquer le numéro comme invalide en base de données
            await markPhoneAsInvalid(recipientPhone);
            await logError(messageId, error, 'PHONE_INVALID');
            break;
            
        case 'business_logic':
            if (error.code === 131047) {
                // Fenêtre 24h fermée : envoyer un template à la place
                await sendTemplateMessage(recipientPhone, 'relance_contact');
            } else if (error.code === 131031) {
                // Client a bloqué : ne plus contacter
                await markAsOptOut(recipientPhone);
            }
            break;
            
        case 'transient':
            // Remettre dans la queue pour retry
            await requeueMessage(messageId, Date.now() + 60000);
            break;
            
        default:
            await alertTeam(`Erreur inconnue [${error.code}] pour ${recipientPhone}`);
    }
}

Alertes et monitoring : mettez en place des alertes lorsque le taux d'erreur dépasse un seuil (ex : plus de 5% d'erreurs sur 1000 messages). Des outils comme Sentry, Datadog ou même un simple cron qui surveille vos logs peuvent faire la différence entre une panne détectée en 5 minutes et une panne découverte le lendemain matin.

Consultez le guide complet WhatsApp Business API et l'article sur l'automatisation des flux WhatsApp pour comprendre le contexte global dans lequel s'inscrit cette gestion d'erreurs.

FAQ

Q: Comment distinguer une erreur temporaire d'une erreur définitive dans la réponse API ?

R: En règle générale, les codes HTTP 4xx (sauf 429) indiquent des erreurs côté client (définitives) : numéro invalide, token expiré, permission manquante. Les codes 5xx et le 429 indiquent des erreurs temporaires du serveur ou de rate limit. Pour les erreurs WhatsApp spécifiques, référez-vous à la liste des codes dans la documentation officielle Meta.

Q: Combien de tentatives de retry faut-il implémenter ?

R: Entre 3 et 5 tentatives avec un backoff exponentiel est une bonne pratique générale. Pour les erreurs de rate limit, respectez le délai indiqué par l'API. Au-delà de 5 tentatives sans succès, il vaut mieux déplacer le message dans une "dead letter queue" pour investigation manuelle plutôt que de continuer à retenter indéfiniment.

Q: Que faire si mon token d'accès expire en cours d'opération ?

R: Mettez en place un mécanisme de refresh automatique du token. Détectez le code 190, rafraîchissez le token via l'API Meta, puis relancez la requête. Pour les tokens système (System User Tokens), configurez une alerte avant expiration et renouvelez-les proactivement. Les tokens permanents (non-expiring) sont recommandés pour les applications en production.

Q: Comment gérer les erreurs de webhook (quand mon serveur ne peut pas traiter un événement) ?

R: Toujours retourner un HTTP 200 à Meta dès réception, même si votre traitement échoue ensuite. Stockez le payload dans une queue persistante avant de traiter. Si le traitement échoue, rejouez depuis la queue. Ne dépendez jamais des retries automatiques de Meta comme seul mécanisme de fiabilité.

Q: L'erreur 131047 ("Message non autorisé hors fenêtre 24h") est-elle contournable ?

R: Non, et vous ne devez pas chercher à la contourner. C'est une règle de Meta pour protéger les utilisateurs contre le spam. La bonne pratique est d'avoir des templates HSM approuvés pour ré-engager les clients inactifs. Ces templates sont les seuls messages autorisés pour initier une conversation après 24h sans interaction.


Gérez vos intégrations WhatsApp avec sérénité. Whakup absorbe la complexité de la gestion des erreurs, des retries et des rate limits pour vous permettre de vous concentrer sur votre business.

#gestion erreurs whatsapp api#codes erreur whatsapp#retry logic api#whatsapp business api#robustesse api
Pablo Lenormand
Pablo LenormandCo-fondateur & CPO

Co-fondateur et Chief Product Officer de Whakup, Pablo conçoit les fonctionnalités qui permettent aux marques africaines de maximiser leur impact sur WhatsApp.

🚀

Prêt à passer à l'action ?

Essayez Whakup gratuitement pendant 15 jours. Aucune carte bancaire requise.

Démarrer l'essai gratuit