# WP_Error et sa méthode add_data : joindre un code HTTP à une erreur

> Une erreur WordPress n'a pas de code HTTP par défaut. Voici comment en attacher un proprement à un objet WP_Error, sans créer de sous-classe.

- Auteur : WordPress Développement
- Publié le : 2022-12-20
- Mis à jour le : 2022-12-20
- Catégorie : Astuces
- URL : https://www.wpmoderne.fr/tips/wp-error-add-data-code-http/

## L’essentiel

- add_data() attache un statut à une erreur existante
- Le statut se lit ensuite via get_error_data()
- Compatible avec les erreurs REST renvoyées au client

`new WP_Error( 'invalid_id', "L'identifiant fourni n'existe pas." )` : voilà à quoi ressemble la majorité des erreurs qu'on lève dans un plugin. Le problème apparaît dès qu'on doit renvoyer cette erreur à un client REST ou Ajax : sans indication de statut, l'appelant ne sait pas s'il doit afficher un message, rediriger l'utilisateur ou réessayer plus tard.

La classe `WP_Error` propose justement une méthode pensée pour ce cas précis : `add_data()`. Elle permet d'associer des données arbitraires — dont un code HTTP — à un code d'erreur donné, sans toucher à la structure de la classe ni écrire de sous-classe dédiée.

## Ce que WP_Error stocke par défaut

Un objet `WP_Error` repose sur trois propriétés internes : un tableau de codes, un tableau de messages associés à ces codes, et un tableau de données additionnelles. Quand on écrit `new WP_Error( 'code_erreur', 'Message lisible' )`, seules les deux premières sont renseignées. La troisième reste vide tant qu'on n'appelle pas explicitement une méthode pour la remplir.

C'est là que beaucoup de développeurs s'arrêtent, en se contentant de vérifier `is_wp_error()` côté appelant puis en renvoyant un statut 400 fixe, quelle que soit la nature réelle du problème. Un identifiant introuvable et une permission refusée méritent pourtant des codes différents.

## Utiliser add_data() pour attacher un statut

> L'essentiel à retenir : add_data() attache un statut à une erreur existante ; Le statut se lit ensuite via get_error_data() ; Compatible avec les erreurs REST renvoyées au client

La signature est volontairement simple : `add_data( $data, $code = '' )`. Le second paramètre est facultatif : s'il est omis, WordPress associe la donnée au dernier code d'erreur ajouté à l'objet. Dans la pratique, on l'explicite presque toujours pour éviter toute ambiguïté quand plusieurs erreurs cohabitent.

```
function trouver_commande( $id ) {
    $commande = get_post( $id );

    if ( ! $commande || 'commande' !== $commande->post_type ) {
        $erreur = new WP_Error(
            'commande_introuvable',
            'Aucune commande ne correspond à cet identifiant.'
        );
        $erreur->add_data( array( 'status' => 404 ), 'commande_introuvable' );
        return $erreur;
    }

    return $commande;
}
```

La clé `status` n'a rien de magique en elle-même : c'est une convention que l'écosystème WordPress a adoptée, notamment dans l'API REST, pour signifier « voici le code HTTP à renvoyer ». On peut tout à fait y ajouter d'autres clés utiles, comme un identifiant de journalisation interne ou un champ destiné au front.

## Relire la donnée associée

Côté appelant, la lecture se fait avec `get_error_data()`, qui accepte lui aussi un code d'erreur optionnel :

```
$resultat = trouver_commande( $id );

if ( is_wp_error( $resultat ) ) {
    $donnees = $resultat->get_error_data( 'commande_introuvable' );
    $statut  = isset( $donnees['status'] ) ? $donnees['status'] : 500;

    wp_send_json_error( $resultat->get_error_message(), $statut );
}
```

Ce petit détour évite d'écrire une classe `My_Custom_Error extends WP_Error` juste pour ajouter une propriété de statut : la classe native suffit largement, et rester dessus garantit la compatibilité avec toutes les fonctions qui manipulent déjà des objets `WP_Error` dans le cœur.

## Plusieurs jeux de données sur une même erreur

Un point souvent ignoré : `add_data()` peut être appelée plusieurs fois pour des codes différents sur le même objet. WordPress autorise en effet un objet `WP_Error` unique à porter plusieurs codes d'erreur, chacun avec son propre message et ses propres données.

- Un code par type de problème rencontré (validation, permission, ressource manquante).
- Une donnée `status` propre à chaque code, pour renvoyer le bon statut selon le cas déclenché.
- Une méthode `get_error_codes()` pour lister tous les codes présents avant de choisir lequel traiter en priorité.

Cette souplesse est particulièrement utile dans une fonction de validation qui accumule plusieurs erreurs avant de les renvoyer d'un coup, plutôt que de s'arrêter à la première anomalie détectée.

## Éviter les pièges classiques

Une erreur fréquente consiste à appeler `add_data()` sans préciser le code alors que l'objet en contient déjà plusieurs : la donnée finit alors attachée au dernier code ajouté, pas forcément à celui qu'on visait. Autre piège : oublier que `get_error_data()` sans argument renvoie la donnée du premier code enregistré, ce qui peut surprendre si l'ordre d'ajout n'est pas celui qu'on imaginait.

Sur un projet où plusieurs fonctions de validation s'enchaînent, mieux vaut donc toujours passer le code explicitement, dans les deux sens, écriture comme lecture. Le gain en clarté du code compense largement les quelques caractères supplémentaires.

> Systématiser une clé `status` sur toutes les erreurs métier d'un projet évite de retomber, six mois plus tard, sur un statut 500 générique là où un 404 ou un 409 aurait mieux renseigné le client.

## Notre verdict

`add_data()` ne réinvente rien de spectaculaire, mais elle règle un vrai manque : donner du sens HTTP à une erreur métier sans complexifier la hiérarchie de classes du projet. Sur une API interne construite avec les briques natives de WordPress, adopter systématiquement cette convention rend chaque retour d'erreur immédiatement exploitable côté client, sans dictionnaire de correspondance à maintenir à part.
