Chapitre 20Exploiter
Dépannage et pièges connus
Par symptôme : ce qu'on observe, ce que c'est, ce qu'on fait. Plus les dix pièges dans lesquels on tombe même en les connaissant.
Où regarder, dans l'ordre
-
La console du navigateur
L'overlay y écrit le détail technique de ce que le client voit en langage courant. C'est le premier endroit quand « ça ne marche pas » vient d'un client.
-
Les journaux de la fonction, chez l'hébergeur
[save],[upload],[content],[auth]: la cause y est nommée, jamais le secret. -
Le journal de build
Si le contenu est publié mais que le site n'a pas changé, c'est ici que ça se passe.
-
Le dépôt
Le commit est-il arrivé ? Sur quelle branche ? Avec quel auteur ?
Au démarrage
| Symptôme | Cause | Correctif |
|---|---|---|
/admin répond 404 |
Site servi par npm run dev sans build, ou intégration absente d'astro.config.mjs. |
npm run build puis npm run serve:functions. |
/api/* répond 404 |
Le serveur Astro seul ne sert pas /functions. |
npm run serve:functions. |
| « Charte introuvable » | src/styles/theme.css manque, ou l'option theme pointe ailleurs. |
Créer le fichier, ou corriger l'option. |
| L'intégration refuse de démarrer | output n'est pas 'static'. |
Règle 1 : la sortie statique n'est pas négociable. |
| « Code de langue invalide » | Une langue déclarée hors du format à deux lettres minuscules. | Corriger locales. |
À l'authentification
| Symptôme | Cause | Correctif |
|---|---|---|
| « Clé incorrecte » avec la bonne clé | EDITOR_KEY_HASH absent ou d'une autre génération. Les variables ne sont relues qu'au (re)démarrage. |
Vérifier .dev.vars ou les secrets, puis redémarrer. |
| Message d'attente après cinq essais | La limitation de débit fonctionne. | Attendre le quart d'heure. Ce n'est pas une panne. |
| La session est perdue à chaque page | Site servi en HTTP : le cookie porte Secure et n'est pas envoyé. |
Passer en HTTPS. En local, 127.0.0.1 est traité comme une origine sûre. |
| Toutes les sessions tombent d'un coup | SESSION_SECRET a changé. |
Normal : c'est l'effet recherché lors d'une rotation. |
| Cinq clés fausses passent sans message d'attente | La liaison RATE_LIMIT manque, ou le compteur est en mémoire. |
Ne pas livrer. Déclarer la liaison chez l'hébergeur. |
À la publication
| Journal | Cause | Correctif |
|---|---|---|
[save] écriture impossible (not_found) | GIT_REPO mal écrit, branche absente, ou jeton sans accès. | Vérifier les trois, puis test-git-provider --online. |
[save] écriture impossible (unauthorized) | Jeton expiré, révoqué, ou permission Contents absente. | Régénérer le jeton, à portée restreinte. |
[save] écriture impossible (conflict) | Le fichier a changé depuis l'ouverture de la page. | Le client recharge et republie. Si c'est systématique, un autre processus écrit dans le dépôt. |
[save] contenu refusé par le schéma | Une valeur hors enum, un alt vide, un titre trop long. | Le chemin fautif est dans le journal. Rare depuis l'interface, courant en appel direct. |
[save] contenu refusé : référence de média invalide | Une image hors liste blanche, ou un identifiant vidéo incohérent. | Vérifier le nom de fichier et le couple fournisseur/identifiant. |
[save] contenu refusé : balisage manifestement hostile | La route a été appelée directement avec du balisage interdit. | Rien à corriger : c'est le comportement attendu. |
| Le commit est rejeté par la forge | Protection de branche : revue ou contrôle obligatoire. | Autoriser le compte machine, ou lever la contrainte sur cette branche. |
Après la publication
| Symptôme | Cause |
|---|---|
| Le commit est là, le site ne change pas | L'hébergeur n'écoute pas cette branche, ou le build échoue. Lire le journal de build. |
| Le build échoue après une publication | Presque impossible : la fonction valide avec le même schéma. Chercher plutôt une image référencée mais absente de src/media. |
| L'image est publiée mais ne s'affiche pas | Le fichier est dans le dépôt, le HTML n'est pas encore reconstruit. Attendre la fin du build. |
| Le site est à jour, le navigateur montre l'ancien | Cache du navigateur. Rechargement forcé. |
Aux contrôles
| Échec | Cause la plus fréquente |
|---|---|
check-html : une valeur manque dans le HTML | Une directive client:* sur un composant de contenu. |
check-html : zone éditable dans une île hydratée | client:load autour d'un data-cms. Sortir la zone de l'île. |
check-html : data-cms sans clé | Une clé renommée dans le JSON, pas dans la page. |
check-locales : clé absente d'une langue | Un champ ajouté dans une seule langue. |
check-logs : journal suspect | Un console.error(error) ajouté pour déboguer. |
check-secrets : secret dans le build | Une variable posée en variable de build au lieu d'un secret d'exécution. |
| Le contrôle passe alors qu'une page est cassée | La page n'est pas dans la liste de check-html.mjs. |
Les dix pièges connus
-
client:loadposé par réflexeLe piège numéro un du projet. Le contenu est bien dans le HTML, mais le framework le réaffiche au chargement et efface les modifications en cours du client. Invisible dans la source.
check-htmlest le filet ; la vigilance en revue passe avant. -
La tentation du mode serveur
Pour « simplifier » une route dynamique. Toujours passer par
/functions: la sortie statique est ce qui garantit que le contenu est dans le HTML servi. -
Les endpoints
src/pages/api/*Ils semblent fonctionner en développement et ne font rien en production statique : ils s'exécutent au build, pas à la requête.
-
Un champ ajouté dans une seule langue
check-localesdoit le détecter avant le commit — encore faut-il le lancer. -
Un identifiant d'item réattribué
Casse le lien DOM/JSON et fait perdre les modifications de l'item. Un identifiant ne se réutilise jamais, même après suppression.
-
Une collection sans son modèle d'item
L'ajout devient impossible sans réécrire du rendu côté client. Le composant
Collectionl'évite ; un rendu de liste écrit à la main, non. -
L'overlay dupliqué site par site
Il doit rester une dépendance partagée et versionnée. Au-delà de trois sites, la maintenance devient ingérable.
-
Le copier-coller depuis un traitement de texte
Le client le fera dès la première semaine. Sans écrasement complet des styles en ligne, la page se retrouve avec du Calibri 11 pt en plein milieu de la charte.
-
La vérification de la clé côté client
Raccourci tentant lors du développement de l'overlay, et faille totale. La clé part vers
/api/auth, jamais ailleurs. -
L'oubli de la limitation de débit
Le code fonctionne parfaitement sans elle, ce qui la rend facile à repousser « pour plus tard ». Elle fait partie du premier lot, pas du durcissement final.
La fuite de jargon dans un message affiché. C'est par là que le vocabulaire technique revient dans l'interface. Vérifier chaque chaîne affichée, y compris les messages d'erreur ajoutés en urgence.
Questions fréquentes
Le client peut-il casser le site ?
Non. Un contenu invalide est refusé avant d'entrer dans le dépôt, par le même schéma que celui du build. Et chaque publication étant un commit, tout état antérieur est restaurable.
Que se passe-t-il si deux personnes éditent en même temps ?
La seconde publication est refusée avec un message de conflit. Rien n'est écrasé, et le brouillon local n'est pas perdu : recharger, republier.
Peut-on éditer depuis un téléphone ?
Non, et c'est délibéré : l'édition de texte sur petit écran donne un mauvais résultat. Un message l'explique plutôt que de livrer une interface dégradée.
Combien de temps avant qu'une modification soit en ligne ?
Trente à soixante secondes : le temps de reconstruire le site. C'est annoncé dans l'interface.
Que voit un visiteur qui n'a pas la clé ?
Le site, et 175 octets de JavaScript qui lisent un cookie. L'overlay n'est pas téléchargé.
Peut-on retrouver une clé perdue ?
Non : seule son empreinte existe côté serveur. Elle se régénère — c'est la procédure de rotation.
Peut-on héberger ailleurs que sur Cloudflare Pages ?
Oui, et sans écrire une ligne : un site créé porte déjà trois adaptateurs — celui d'un
hébergeur qui découvre les routes par l'arborescence, celui de Netlify, et un serveur Node
pour tout le reste. Les dossiers inutilisés se suppriment. Ailleurs encore, il n'y a qu'un
fichier à écrire, qui appelle api.handle et ne décide rien. Voir
Déploiement.
Le site s'affiche, mais la clé est refusée — 404 ou 502 sur /api/auth
Ce n'est pas la clé. Un site déposé sans ses fonctions s'affiche parfaitement et n'a aucune
route : curl -i https://le-site.fr/api/auth doit répondre 405. Du
HTML ou un 404 veut dire que les fonctions ne tournent pas. Sur Netlify, un
502 « handler is not a function » a une cause précise :
node_bundler déclaré dans netlify.toml, qui fait produire du
CommonJS et prendre la fonction pour une v1. Retirer la ligne.