« Pourquoi peut-on tomber trois fois dans le même trou ? — Journal de réparations à répétition de zidongjiexi (avec des leçons systématiques) »
Certains bugs sont comme l’adolescence : tu crois que c’est passé, ils reviennent avec une autre coupe de cheveux.
Cette panne deastrbot_plugin_zidongjiexiplusyoutubexiazaien est l’exemple типique : à chaque fois, ça a l’air “réparé”, mais à la prochaine relance ça repart en vrille.
I. Chronologie de l’incident : de « l’erreur PIL » à la « compatibilité d’environnement »
Phase 1 : première erreur (crash au chargement des ressources)
Au démarrage du plugin, ça déclenche dans render.py, à _load_video_button :
img.convert("RGBA")AssertionErrorinterne à Pillow
Conclusion intuitive : il y a un risque lors du décodage de la ressource media_button.png (image potentiellement anormale, ou bien différence de chemin de décodage à l’exécution).
Phase 2 : première correction (succès en apparence)
Après une ré-enregistrement de la ressource (RGBA), redémarrage immédiat OK.
On en déduit donc facilement que « le problème est résolu ».
Phase 3 : rechute (re-crash au même endroit)
Aux redémarrages suivants, ça re-plante. Cela montre que le problème n’est pas juste « le fichier était corrompu une fois », mais que :
- le chemin de code manque de tolérance aux erreurs ;
- selon l’état d’exécution, le plugin peut encore déclencher des échecs de décodage similaires.
Phase 4 : lors de la deuxième correction, « la correction introduit un nouveau problème »
Pendant l’application du patch, deux types d’incidents secondaires classiques sont apparus :
- Erreur introduite au niveau syntaxique (mauvaise gestion des commentaires/chaînes) provoquant un
SyntaxError; - Différences de version des bibliothèques de l’environnement rendant les paramètres de
EmojiCDNSourceincompatibles (enable_tqdmn’est pas supporté).
Au final, convergence via retour à un fichier stable + modifications incrémentales minimales + vérification de compilation + validation par redémarrage.
II. Analyse de la cause racine : pourquoi « réparé » peut encore « re-casser »
1) « Réussir une fois » ≠ « correction systémique »
Ré-enregistrer une image élimine juste l’échantillon problématique du moment ; cela ne garantit pas que le même chemin ne sera pas re-déclenché plus tard.
2) Le code du plugin manque de stratégie de dégradation pour les ressources critiques
Les ressources sont des dépendances externes. Une dépendance externe doit pouvoir « échouer sans être fatale ».
3) L’environnement d’exécution n’est pas constant
Un même plugin, dans des images de conteneur différentes ou avec des versions de dépendances différentes, peut initialiser différemment.
Par exemple, ici la différence de compatibilité des paramètres de apilmoji n’est pas une erreur de logique métier, mais un couplage aux versions de l’écosystème.
4) Le processus de correction manque de « barrières de contraintes fortes »
Sans faire immédiatement, après chaque patch, les validations forcées ci-dessous, on peut facilement repasser d’un « état exécutable » à un « état d’erreur de syntaxe » :
- vérification syntaxique
py_compile - validation d’un démarrage à froid minimal
- assertion sur les logs de chargement des plugins clés
III. Ce que la correction finale a fait
zidongjiexi
- Ajout d’une logique de tolérance aux erreurs dans
_load_video_button:img.load()pour forcer le décodage à l’avance ;- en cas d’exception, dégradation vers une image de substitution transparente, afin d’éviter l’échec du démarrage global du plugin.
- Suppression du paramètre incompatible
enable_tqdmdeEmojiCDNSource, pour s’adapter à l’environnement actuel. - Plusieurs validations par redémarrage, confirmant que le plugin peut entrer de façon stable dans l’état « chargé ».
memelite (corrigé au passage)
- Correction de l’absence de
libEGL.so.1: installation delibegl1/libgl1, éliminant la boucle de restauration de dépendances au démarrage.
IV. Pourquoi ce redémarrage est passé de 20 secondes à 600+ secondes
Ce n’est pas « la machine qui est soudain devenue lente », mais un élément bloquant s’est ajouté dans la chaîne de démarrage :
memeliterestaure les dépendances à répétition + le processus pip allonge le démarrage ;- Les échecs répétés de chargement de plugins augmentent le temps d’initialisation global ;
- La tempête de logs d’erreur (y compris des anomalies de format de logs tiers) amplifie encore la sensation de blocage.
Version en langage humain : ce n’est pas AstrBot qui a pris un coup de vieux en une nuit, c’est qu’il répare un pneu en même temps qu’il se lève.
V. Leçons d’ingénierie (encore plus précieuses que la correction du bug)
Leçon 1 : le chargement de ressources doit être « survivable en cas d’échec »
Images, polices, CDN externes, fichiers Cookie… on ne peut pas supposer qu’ils seront toujours sains.
Tolérance aux erreurs + dégradation est le plancher de maintenabilité d’un plugin.
Leçon 2 : une correction doit suivre une « boucle de changements minimaux »
Processus recommandé :
- Revenir d’abord à une base stable connue ;
- Ne modifier qu’un seul endroit ;
- Faire une validation de syntaxe / un contrôle ponctuel ;
- Redémarrer pour valider ;
- Puis seulement passer à la modification suivante.
Leçon 3 : une « réparation » doit inclure une validation répétable
« Chez moi ça marche » n’a aucun sens ; il faut pouvoir confirmer « ça marche encore » à travers des redémarrages et des périodes de temps différentes.
Leçon 4 : attention au couplage global du format des logs
Si les champs de logs d’une bibliothèque tierce ne correspondent pas au format de logs de ton système, cela peut générer du bruit, voire gêner le diagnostic.
On peut envisager un handler séparé pour le logger tiers, ou bien abaisser le niveau de logs.
VI. Recommandations pour la suite (éviter la redite la prochaine fois)
- Ajouter au plugin une commande d’auto-vérification au démarrage (vérifier les fichiers de ressources, versions de dépendances, configuration clé) ;
- Ajouter dans la CI ou le script de release :
- vérification de syntaxe
- test d’import minimal
- smoke test des fonctions d’initialisation critiques
- Adopter une stratégie de dégradation unifiée pour les ressources « non cœur de fonctionnalité » ;
- Mettre en place un « seuil d’alerte sur le temps de redémarrage » (par ex. >90s) et capturer automatiquement les logs des points lents.
Conclusion
Le plus précieux dans cet incident, ce n’est pas « enfin c’est réparé », mais le fait d’avoir confirmé :
- qu’une correction réellement livrable n’est pas un sauvetage manuel ponctuel ;
- mais le passage d’un système « qui démarre à la chance » à un système « qui démarre de façon prévisible ».
Si les bugs sont là pour encaisser une taxe sur le QI, au moins cette fois on a gardé la facture. ![]()