Prob de refresh aleatoire dans design

Suite a des prob apparemment aléatoires de mise à jour de certain widget dans mes designs j’ai fait travailler mythos sur ce problème et il a fini (en 1h30 quand même !!! :slight_smile: ) par identifier le prob.

Je joins, pour la team Jeedom ce qu’il suggère (et qui marche, je l’ai testé)

Problème

refreshValue (eqLogic.class.js) : un template widget commençant par un commentaire HTML fige le rafraîchissement de TOUS les widgets des designs (TypeError non attrapée)

Description

Dans core/js/eqLogic.class.js, le handler des événements eqLogic::update (jeedom.eqLogic.refreshValue) suppose que le premier nœud du HTML renvoyé par toHtml est l’élément racine du widget :

tile = domUtils.parseHTML(result[i].html)
...
uid = tile.childNodes[0].getAttribute('data-eqLogic_uid')   // L569
...
eqLogic.classList.add(...tile.childNodes[0].classList)      // L574
if (!tile.childNodes[0].hasClass('eqLogic_layout_table')) { // L575
if (!tile.childNodes[0].hasClass('eqLogic_layout_default')) // L578

Si le template du plugin commence par un commentaire HTML (<!-- ... -->), une ligne vide ou une simple espace/tabulation, childNodes[0] est un nœud commentaire (nodeType 8) ou texte (nodeType 3), qui n’a pas de méthode getAttribute :

TypeError: tile.childNodes[0].getAttribute is not a function
    at Object.success (core/js/eqLogic.class.js:569)

Conséquence aggravante

Cette ligne est HORS du try/catch (qui ne couvre que eqLogic.empty().appendChild(tile)). L’exception avorte donc la boucle for (const i in result) entière : tous les équipements restants du lot d’événements ne sont plus re-rendus. Concrètement, un seul plugin dont le template commence par un commentaire fige le rafraîchissement de la quasi-totalité des widgets d’un design, y compris ceux de plugins parfaitement sains — symptôme intermittent (« widgets à moitié à jour ») très difficile à diagnostiquer, car les valeurs cmd::update continuent, elles, d’arriver.

Constaté en production sur Jeedom 4.6.1 (page plan/design) ; le code est identique sur les branches master et develop.

Reproduction minimale

  1. Prendre un plugin avec template widget personnalisé (core/template/dashboard/monplugin.html) et ajouter une ligne <!-- commentaire --> en toute première ligne, avant le <div> racine.
  2. Placer un équipement de ce plugin sur un design, avec au moins un autre équipement (d’id supérieur) sur le même design.
  3. Déclencher côté PHP $eqLogic->refreshWidget(); (ou n’importe quel événement eqLogic::update).
  4. Console navigateur : TypeError à eqLogic.class.js:569 ; le widget n’est pas re-rendu, et les équipements suivants du lot non plus.

Correctif suggéré

  1. Utiliser firstElementChild (supporté par le DocumentFragment que renvoie domUtils.parseHTML) à la place de childNodes[0] aux 4 occurrences :
const tileRoot = tile.firstElementChild
if (tileRoot == null) continue
uid = tileRoot.getAttribute('data-eqLogic_uid')
...

À noter : le core possède déjà la version robuste de ce parcours — domUtils.DOMparseHTML (core/dom/dom.utils.js:375) ignore explicitement les nœuds non-éléments (_child.tagName != undefined). refreshValue utilise la variante naïve.

  1. Encadrer le traitement de chaque itération de la boucle dans un try/catch (avec console.error), pour qu’un widget mal formé ne bloque plus le rafraîchissement de tous les autres.

  2. Même motif dans core/js/cmd.class.js:418 (jeedom.cmd.refreshByEqLogic, marquée deprecated et apparemment appelée nulle part : à corriger ou à supprimer).

Environnement

  • Jeedom 4.6.1, Debian, PHP 8.x
  • Reproduit sur page plan (design), navigateur Chromium 151
1 « J'aime »