Combien de blocs interactifs une agence peut-elle livrer avant qu’une erreur silencieuse, jamais remontée nulle part, ne finisse par coûter plus cher qu’un système de monitoring correctement configuré ? Depuis la stabilisation de l’Interactivity API en avril 2024 avec WordPress 6.5, plusieurs blocs construits sur cette API ont été livrés à des clients différents — filtres de catalogue, formulaires multi-étapes, compteurs animés — sans qu’aucun dispositif commun de capture d’erreur client n’ait été mis en place. Un incident chez l’un des clients, resté invisible plusieurs jours, a précipité la mise en place d’un monitoring systématique.
Le SDK Sentry pour navigateur (@sentry/browser) capture par défaut les exceptions non interceptées et les rejets de promesses non gérés. Mais le fonctionnement propre aux stores de l’Interactivity API, dont les actions peuvent être des générateurs asynchrones exécutés dans un contexte particulier, laisse passer certaines erreurs sans qu’elles remontent jamais jusqu’au gestionnaire global window.onerror attendu par Sentry.
Pourquoi les erreurs de store échappent au capteur global
Une action de store définie avec une fonction génératrice, utilisée pour gérer des appels asynchrones via yield, peut lever une exception qui reste piégée dans le mécanisme interne d’exécution des générateurs du moteur de l’Interactivity API. Selon la version exacte du runtime et la façon dont l’appel est déclenché (directive data-wp-on, effet réactif), cette exception n’atteint pas toujours le gestionnaire global capturé automatiquement par Sentry, contrairement à une erreur synchrone classique levée dans un script standard.
Envelopper chaque action avec une capture explicite
La solution retenue consiste à ne jamais déclarer une action de store directement, mais à systématiquement l’envelopper dans une fonction utilitaire qui capture toute exception avant de la relancer, garantissant qu’elle atteigne Sentry quel que soit le comportement interne du moteur :

// utils/avec-capture-sentry.js
import * as Sentry from '@sentry/browser';
export function avecCaptureSentry( nomAction, fonction ) {
return async function ( ...args ) {
try {
return await fonction.apply( this, args );
} catch ( erreur ) {
Sentry.captureException( erreur, {
tags: { 'interactivity-action': nomAction },
} );
throw erreur;
}
};
}
import { store, getContext } from '@wordpress/interactivity';
import { avecCaptureSentry } from '../utils/avec-capture-sentry';
store( 'acme/filtre-catalogue', {
actions: {
appliquerFiltre: avecCaptureSentry( 'appliquerFiltre', function* ( event ) {
const context = getContext();
context.chargement = true;
const response = yield fetch( `/wp-json/acme/v1/produits?categorie=${ event.target.value }` );
if ( ! response.ok ) {
throw new Error( `Erreur API produits : ${ response.status }` );
}
context.produits = yield response.json();
context.chargement = false;
} ),
},
} );
Ce wrapper garantit deux choses : l’exception est systématiquement capturée par Sentry avec une étiquette identifiant précisément quelle action de quel store est en cause, et elle continue d’être relancée (throw erreur) pour ne pas masquer artificiellement un dysfonctionnement à l’utilisateur ou au reste du code applicatif.
Enrichir le contexte envoyé à Sentry
Une erreur brute, sans contexte, est peu exploitable sur un parc de plusieurs sites clients. Le wrapper a été enrichi pour inclure automatiquement l’espace de nom du store et l’état courant du contexte au moment de l’erreur, tout en excluant explicitement les champs sensibles (jamais d’adresse e-mail ou de donnée personnelle transmise à Sentry) :
- Nom du store et de l’action concernée, ajoutés systématiquement en tags Sentry pour faciliter le filtrage par client et par bloc.
- Extrait non sensible du contexte réactif au moment de l’erreur, utile pour reproduire le scénario en local.
- Nom du client et de l’environnement (production, recette), configuré une seule fois au niveau de l’initialisation globale de Sentry plutôt que dans chaque bloc.
Ce que ce dispositif a permis de détecter
Une fois ce wrapper généralisé à l’ensemble des blocs interactifs de l’agence, plusieurs erreurs jusque-là invisibles sont remontées en quelques semaines : un filtre de catalogue qui échouait silencieusement sur une catégorie contenant un caractère spécial mal encodé dans l’URL, et un compteur animé qui levait une exception sur les navigateurs ne supportant pas encore une méthode d’API récente utilisée sans vérification préalable.
Sur un parc de blocs interactifs livrés à plusieurs clients, je considère un wrapper de capture d’erreur systématique comme aussi indispensable que la validation des attributs de bloc elle-même : sans lui, une agence découvre ses bugs par les tickets de support, jamais par son monitoring.
En résumé
L’Interactivity API, bien que stabilisée depuis WordPress 6.5, introduit un modèle d’exécution suffisamment différent de React classique pour que les réflexes habituels de capture d’erreur ne suffisent plus tels quels. Envelopper systématiquement chaque action de store dans une fonction de capture explicite comble cette lacune, sans exiger de changement sur le fonctionnement normal du bloc.