FR EN

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.

7 min de lecture16 sectionsChapitre 20 / 22

Où regarder, dans l'ordre

  1. 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.

  2. Les journaux de la fonction, chez l'hébergeur

    [save], [upload], [content], [auth] : la cause y est nommée, jamais le secret.

  3. Le journal de build

    Si le contenu est publié mais que le site n'a pas changé, c'est ici que ça se passe.

  4. Le dépôt

    Le commit est-il arrivé ? Sur quelle branche ? Avec quel auteur ?

Au démarrage

SymptômeCauseCorrectif
/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ômeCauseCorrectif
« 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

JournalCauseCorrectif
[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émaUne 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 invalideUne 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 hostileLa route a été appelée directement avec du balisage interdit.Rien à corriger : c'est le comportement attendu.
Le commit est rejeté par la forgeProtection de branche : revue ou contrôle obligatoire.Autoriser le compte machine, ou lever la contrainte sur cette branche.

Après la publication

SymptômeCause
Le commit est là, le site ne change pasL'hébergeur n'écoute pas cette branche, ou le build échoue. Lire le journal de build.
Le build échoue après une publicationPresque 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 pasLe 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'ancienCache du navigateur. Rechargement forcé.

Aux contrôles

ÉchecCause la plus fréquente
check-html : une valeur manque dans le HTMLUne directive client:* sur un composant de contenu.
check-html : zone éditable dans une île hydratéeclient: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 langueUn champ ajouté dans une seule langue.
check-logs : journal suspectUn console.error(error) ajouté pour déboguer.
check-secrets : secret dans le buildUne 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éeLa page n'est pas dans la liste de check-html.mjs.

Les dix pièges connus

  1. client:load posé par réflexe

    Le 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-html est le filet ; la vigilance en revue passe avant.

  2. 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.

  3. 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.

  4. Un champ ajouté dans une seule langue

    check-locales doit le détecter avant le commit — encore faut-il le lancer.

  5. 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.

  6. Une collection sans son modèle d'item

    L'ajout devient impossible sans réécrire du rendu côté client. Le composant Collection l'évite ; un rendu de liste écrit à la main, non.

  7. 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.

  8. 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.

  9. 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.

  10. 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.

Et un onzième, d'exploitation

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.