Files
nas-runbooks/hermes-tt/mail-o365-hermes-mail-browser-inbox-staleness.md

4.0 KiB

hermes-mail-browser — /inbox renvoyait des mails perimes (staleness liste virtualisee OWA)

Date : 2026-07-24 Sphere : hermes-tt Composant : hermes-mail-browser (port 3110, service Playwright/Edge headless pilotant OWA)

Symptome

Nabil signale que hermes-tt "ne voit pas les mails convenablement". Verification : GET /inbox?limit=5 renvoyait 5 mails dates du samedi 18/07, avec un doublon (meme item en position 1 et 4), alors que la vraie boite avait des mails recus le jour meme (24/07). GET /auth/status montrait current_url pointant sur un message ouvert (.../mail/inbox/id/AAkA...), pas sur la racine de la boite.

Cause racine

Le service garde un seul onglet Edge partage entre tous les appels (get_owa_page() reutilise l'onglet existant sans jamais y renaviguer tant que le host correspond a OWA — meme si le chemin pointe vers un message ouvert). Les endpoints /message/{index}, /message/{index}/attachments et /message/{index}/attachments/{filename}/text font tous un .click() sur l'option a l'index demande pour ouvrir le message. Ce clic scrolle la liste virtualisee d'OWA (react-window / virtualisation type outlook) — seuls les elements proches de la position courante restent montes dans le DOM. Si /inbox est appele ensuite sans navigation fraiche, le selecteur [role="listbox"]...[role="option"] lit les items actuellement montes, pas le sommet reel de la boite → mails perimes, ordre incoherent, doublons possibles aux frontieres de rendu virtualise.

Le bug ne se declenche pas au premier appel (onglet fraichement ouvert = sommet de la liste) mais des qu'un /message/{index} a ete appele avant — ce qui est le cas d'usage normal (hermes-tt lit l'inbox, ouvrait un message il y a plusieurs jours, puis relit l'inbox → resultat foireux persistant jusqu'au prochain redemarrage du conteneur).

Fix

Nouvelle fonction go_to_inbox_root(page) dans main.py : force un page.goto(OWA_URL, wait_until="domcontentloaded") + attente 2s. Appelee systematiquement en tete de logique dans les 4 endpoints qui lisent la liste par index : /inbox, /message/{index}, /message/{index}/attachments, /message/{index}/attachments/{filename}/text. Cout : ~2-3s de latence supplementaire par appel, juge acceptable (usage agent ponctuel, pas de boucle haute frequence) au profit de la fiabilite.

Fichier modifie : /volume1/docker/hermes-mail-browser/app/main.py (backup avant patch : main.py.bak_20260724_inbox_staleness). ./app est bake dans l'image (pas de bind mount) → docker compose build puis recreation du conteneur necessaires, pas un simple restart.

Piege rencontre a la recreation (deja documente le 23/07, reconfirme)

data/profile/ est un volume persistant. A la recreation du conteneur, les fichiers de verrou Edge de l'ancien process (SingletonLock, SingletonCookie, SingletonSocket — des symlinks) survivent et bloquent le nouvel Edge au demarrage. Sequence correcte :

  1. docker compose stop hermes-mail-browser (arret propre, pas juste up -d)
  2. rm les 3 fichiers Singleton* dans data/profile/
  3. docker compose up -d
  4. Verifier curl http://192.168.100.33:3110/auth/statusauthenticated:true SANS nouvelle authentification manuelle (cookies conserves, seul le verrou genait).

Validation

Apres fix + rebuild + recreation propre :

  • authenticated:true, current_url = racine /mail/ (pas un message).
  • /inbox : mails du jour meme, bon ordre, pas de doublon.
  • Test de non-regression cible : GET /message/0 (simule un clic anterieur) puis GET /inbox immediatement apres → toujours correct (c'etait precisement le scenario qui cassait avant le fix).

A surveiller

Le cout de go_to_inbox_root() sur /message/{index}/attachments/{filename}/text (deja une operation lente : clic + telechargement + extraction) ajoute un navigate de plus — pas mesure de degradation notable en test manuel mais a garder en tete si hermes-tt rapporte des timeouts sur cet endpoint precis.