Monitoring d’erreurs avancé dans WordPress 7.0 avec wp_trigger_error()

Bonne nouvelle pour les devs, le ticket #60886 a été commit pour la prochaine version de WordPress 7.0 et introduira un changement notable dans le monitoring d’erreurs. La fonction wp_trigger_error(), jusqu’ici limitée aux environnements de développement, devient enfin exploitable en production grâce aux hooks wp_trigger_error_always_run et wp_trigger_error_trigger_error.

Exit la condition sur un paramètre $_GET dans le wp-config.php pour forcer WP_DEBUG temporairement. Plus besoin non plus de jouer avec les fichiers de configuration selon l’environnement. Ces nouveaux hooks s’exécutent systématiquement, que WP_DEBUG soit true ou false.

Dans cet article, on va détailler ce changement et voir comment mettre en place un système de monitoring intelligent et production-ready, c’est parti !

wp_trigger_error() et ses limitations historiques

La fonction wp_trigger_error() a été introduite dans WordPress 6.4 pour standardiser la gestion des erreurs dans le core. C’est une sur-couche à la fonction PHP native trigger_error() qui respecte la configuration WordPress (WP_DEBUG, WP_DEBUG_DISPLAY) et fournit un contexte plus riche.

Le problème majeur avant WordPress 7.0 c’est que les hooks n’étaient disponibles qu’à l’intérieur du bloc conditionnel if ( WP_DEBUG )…. Résultat : impossible de monitorer les erreurs en production sans activer le mode debug et donc afficher les warnings aux visiteurs (enfin, même si des tricks existe pour le faire, il n’y avait rien de natif).

Flux d’exécution AVANT WordPress 7.0

wp_trigger_error()
    ↓
WP_DEBUG ?
    ├─ false → STOP (aucun hook exécuté)
    └─ true
         ↓
         do_action( 'wp_trigger_error_run' )
         ↓
         WP_DEBUG_DISPLAY ?
              ├─ true  → trigger_error() (affichage)
              └─ false → erreur loggée uniquement

Le point de blocage : Si WP_DEBUG = false (cas standard en production), aucun hook n’est exécuté. On ne peut rien capturer.

Flux d’exécution APRÈS WordPress 7.0

wp_trigger_error()
    ↓
do_action( 'wp_trigger_error_always_run' )   ← NOUVEAU (toujours exécuté)
    ↓
apply_filters( 'wp_trigger_error_trigger_error' ) ← NOUVEAU (contrôle fin)
    ↓
WP_DEBUG ?
    ├─ false → STOP (pas d’affichage, mais hooks déjà exécutés)
    └─ true
         ↓
         do_action( 'wp_trigger_error_run' )  ← Hook legacy
         ↓
         WP_DEBUG_DISPLAY ?
              ├─ true  → trigger_error() (affichage)
              └─ false → erreur loggée uniquement

La grande différence : Les nouveaux hooks s’exécutent avant la vérification de WP_DEBUG. On peut maintenant capturer toutes les erreurs sans toucher à la config, sans impact utilisateur/visiteur.

Mise en pratique : Monitoring centralisé en mu-plugin

Passons à la pratique. Voici comment implémenter un système de monitoring qui capture toutes les erreurs sans perturber vos visiteurs.

L’objectif est de capturer systématiquement toutes les erreurs déclenchées via wp_trigger_error() et les enregistrer dans un fichier de log dédié (ici ce sera le debug.log via fonction error_log())

Pour un monitoring global, je vous recommande un mu-plugin (wp-content/mu-plugins/). Les mu-plugins se chargent automatiquement avant tous les autres plugins, garantissant que votre système de monitoring est opérationnel dès le début.

<?php
/**
 * MU Plugin: Monitoring de wp_trigger_error() (WordPress 7.0+)
 *
 * Capture toutes les erreurs via wp_trigger_error(),
 * même si WP_DEBUG est désactivé.
 */

namespace Labside\Monitoring;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

final class WP_Trigger_Error_Monitor {

    /**
     * Initialise les hooks.
     */
    public static function init() {
        add_action(
            'wp_trigger_error_always_run',
            array( __CLASS__, 'handle_error' ),
            10,
            3
        );

        add_filter(
            'wp_trigger_error_trigger_error',
            array( __CLASS__, 'filter_trigger' ),
            10,
            4
        );
    }

    /**
     * Capture systématiquement les erreurs.
     *
     * @param string $function_name
     * @param string $message
     * @param int    $error_level
     */
    public static function handle_error( $function_name, $message, $error_level ) {

        $levels = array(
            E_USER_NOTICE  => 'notice',
            E_USER_WARNING => 'warning',
            E_USER_ERROR   => 'error',
            E_USER_DEPRECATED => 'deprecated',
        );

        $level_label = isset( $levels[ $error_level ] )
            ? $levels[ $error_level ]
            : 'unknown';

        error_log(
            sprintf(
                '[WP_TRIGGER_ERROR][%s] %s(): %s',
                strtoupper( $level_label ),
                $function_name,
                $message
            )
        );
    }

    /**
     * Permet de contrôler si trigger_error() doit être exécuté.
     *
     * @param bool   $trigger
     * @param string $function_name
     * @param string $message
     * @param int    $error_level
     * @return bool
     */
    public static function filter_trigger( $trigger, $function_name, $message, $error_level ) {

        // Exemple : empêcher l'affichage de certaines erreurs en production
        // if ( 'my_sensitive_function' === $function_name ) {
        //     return false;
        // }

        return $trigger;
    }
}


WP_Trigger_Error_Monitor::init();

Et voilà ! Avec cette implémentation vous serez en mesure, avec WordPress 7.0, d’avoir un véritable outil de monitoring en production sans impacter les visiteurs/utilisateurs de votre site !

A très vite, et surtout restez à jour !