Mermaid rendert niet op macOS-desktop (WebView Promise), PDF/PPTX-export van diagram-dia's leeg #882

Closed
opened 2026-07-26 10:30:59 +00:00 by brenno · 2 comments
Owner

Waargenomen bij een native flutter run -d macos (zowel debug als --release) van de app: geen enkel mermaid-diagram rendert tot een diagram. Op elk oppervlak (thumbnail, slidelijst, editor-preview, presentatiemodus) valt het terug op de ruwe mermaid-broncode in een grijs kader. De PDF-export van een mermaid-dia is bovendien vrijwel leeg (alleen het logo + een half vastgelegd laad-tolletje): de rasteraar legt de dia vast vóórdat de (falende) render klaar is.

Oorzaak (achterhaald via de VM-service, niet geraden): elke render gooit

PlatformException(FWFEvaluateJavaScriptError, Failed evaluating JavaScript., Instance of 'NSError', null)

lib/services/mermaid_render_service.dart definieert window.__renderMermaid als een async function (levert een Promise) en roept die aan via runJavaScriptReturningResult('window.__renderMermaid(...)'). macOS-WKWebView kan een Promise-resultaat niet terugmarshalen → exceptie → opgevangen in _run → render levert null → nood-terugval op de brontekst. In een release-build is die log stil.

Reikwijdte: dit raakt het desktop-WebView-renderpad. Het web-pad (JS-interop, #851) rendert wél — daarom is dit op de webdemo (ocideck.librekat.nl) niet zichtbaar en werken #862/#868 dáár. De desktop-app en de PDF/PPTX-export zijn de gedupeerden.

Bestaand, geen regressie: mermaid_render_service.dart is byte-identiek aan origin/main; dit staat los van #872 (dat alleen de layout-/scroll-widgets raakt). Een deck zonder enige #872-relatie faalt precies zo.

Aanbevolen fix (uit de diagnose): laat de WebView de resolved SVG teruggeven i.p.v. de Promise via runJavaScriptReturningResult — bijv. __renderMermaid het resultaat in een variabele laten zetten en dat in een tweede eval-stap uitlezen, of via een JS-channel/postMessage de opgeloste waarde terugsturen. Daarna: een golden of beeldkeuring toevoegen zodat een falende desktop-render niet meer stil door de (nep-renderer-)widgettests glipt.

Blocker-karakter: zolang dit niet werkt, is élke mermaid-dia op desktop leeg/broncode en elke mermaid-PDF-export leeg — en is #872 (scroll) op desktop niet visueel te keuren.

**Waargenomen** bij een native `flutter run -d macos` (zowel debug als `--release`) van de app: **geen enkel mermaid-diagram rendert tot een diagram**. Op elk oppervlak (thumbnail, slidelijst, editor-preview, presentatiemodus) valt het terug op de **ruwe mermaid-broncode** in een grijs kader. De **PDF-export** van een mermaid-dia is bovendien **vrijwel leeg** (alleen het logo + een half vastgelegd laad-tolletje): de rasteraar legt de dia vast vóórdat de (falende) render klaar is. **Oorzaak (achterhaald via de VM-service, niet geraden):** elke render gooit ``` PlatformException(FWFEvaluateJavaScriptError, Failed evaluating JavaScript., Instance of 'NSError', null) ``` `lib/services/mermaid_render_service.dart` definieert `window.__renderMermaid` als een **async function** (levert een Promise) en roept die aan via `runJavaScriptReturningResult('window.__renderMermaid(...)')`. macOS-WKWebView kan een Promise-resultaat niet terugmarshalen → exceptie → opgevangen in `_run` → render levert `null` → nood-terugval op de brontekst. In een release-build is die log stil. **Reikwijdte:** dit raakt het **desktop-WebView-renderpad**. Het **web-pad** (JS-interop, #851) rendert wél — daarom is dit op de webdemo (ocideck.librekat.nl) niet zichtbaar en werken #862/#868 dáár. De desktop-app en de PDF/PPTX-export zijn de gedupeerden. **Bestaand, geen regressie:** `mermaid_render_service.dart` is byte-identiek aan `origin/main`; dit staat los van #872 (dat alleen de layout-/scroll-widgets raakt). Een deck zonder enige #872-relatie faalt precies zo. **Aanbevolen fix (uit de diagnose):** laat de WebView de *resolved* SVG teruggeven i.p.v. de Promise via `runJavaScriptReturningResult` — bijv. `__renderMermaid` het resultaat in een variabele laten zetten en dat in een tweede eval-stap uitlezen, of via een JS-channel/`postMessage` de opgeloste waarde terugsturen. Daarna: een golden of beeldkeuring toevoegen zodat een falende desktop-render niet meer stil door de (nep-renderer-)widgettests glipt. **Blocker-karakter:** zolang dit niet werkt, is élke mermaid-dia op desktop leeg/broncode en elke mermaid-PDF-export leeg — en is #872 (scroll) op desktop niet visueel te keuren.
Author
Owner

Eerste fix-poging (JS-channel i.p.v. Promise) werkt NIET — beeldkeuring op de draaiende macOS-app (debug, tak fix/882-mermaid-macos-render, commit 84cdebf5).

De nieuwe aanroep await _controller!.runJavaScript(window.__renderMermaid(...)) gooit op WKWebView dezelfde FWFEvaluateJavaScriptError (live opgevangen via de VM-service: LOG MermaidRender: render failed + PlatformException code=FWFEvaluateJavaScriptError). Diagram valt terug op ruwe broncode; PDF-export leeg. Ook het bestaande Mermaidkeur-deck faalt identiek → fout zit op WebView-niveau, diagram-onafhankelijk.

Herziene diagnose: het probleem is dus NIET (alleen) het marshalen van een Promise-retourwaarde. De evaluatie van window.__renderMermaid(...) zelf faalt — waarschijnlijk omdat mermaid of window.__renderMermaid op dat moment niet als aanroepbaar in de pagina staat (de inline-setup in loadHtmlString draait niet in WKWebView, of de via een script-element ingebrachte mermaid-bundel laadt daar niet), of WKWebView weigert de evaluatie los van het retour-marshalen.

Volgende stap: diagnostiek toevoegen — tijdens bootstrap via het (nu werkende) MermaidChannel typeof mermaid en typeof window.__renderMermaid terugmelden, om te bepalen óf de setup draait en óf de bundel laadt. Dit vergt trage beeldkeuring-iteraties (elke check = volledige macOS-app-build + -run).

**Eerste fix-poging (JS-channel i.p.v. Promise) werkt NIET** — beeldkeuring op de draaiende macOS-app (debug, tak `fix/882-mermaid-macos-render`, commit 84cdebf5). De nieuwe aanroep `await _controller!.runJavaScript(window.__renderMermaid(...))` gooit op WKWebView **dezelfde** `FWFEvaluateJavaScriptError` (live opgevangen via de VM-service: `LOG MermaidRender: render failed` + `PlatformException code=FWFEvaluateJavaScriptError`). Diagram valt terug op ruwe broncode; PDF-export leeg. Ook het bestaande `Mermaidkeur`-deck faalt identiek → fout zit op WebView-niveau, diagram-onafhankelijk. **Herziene diagnose:** het probleem is dus NIET (alleen) het marshalen van een Promise-retourwaarde. De evaluatie van `window.__renderMermaid(...)` zelf faalt — waarschijnlijk omdat `mermaid` of `window.__renderMermaid` op dat moment niet als aanroepbaar in de pagina staat (de inline-setup in `loadHtmlString` draait niet in WKWebView, of de via een script-element ingebrachte mermaid-bundel laadt daar niet), of WKWebView weigert de evaluatie los van het retour-marshalen. **Volgende stap:** diagnostiek toevoegen — tijdens bootstrap via het (nu werkende) MermaidChannel `typeof mermaid` en `typeof window.__renderMermaid` terugmelden, om te bepalen óf de setup draait en óf de bundel laadt. Dit vergt trage beeldkeuring-iteraties (elke check = volledige macOS-app-build + -run).
Author
Owner

Opgelost — de echte oorzaak was een opstartrace, niet het Promise-marshalen.

Beeldkeuring met ingebouwde diagnostiek gaf de doorslag: de pagina meldt MermaidRender DIAG: setup-ok mermaid=object render=function — mermaid laadt en rendert wél op macOS-WKWebView. De FWFEvaluateJavaScriptError-renders vielen alle in een venster van ~70ms vóór setup-ok: _bootstrapped=true werd gezet zodra loadHtmlString resolvet (= laden gestart), waarna de wachtrij meteen runJavaScript(window.__renderMermaid(...)) afvuurde — maar die functie wordt pas een tel later gedefinieerd wanneer het 3,4MB-pagina-script draait. (Aanvulling op de vorige analyse: runJavaScript negeert javaScriptResultTypeIsUnsupported juist, dus de fout was een échte JS-exceptie = functie nog niet gedefinieerd.)

Fix: de dienst wacht nu op het setup-ok-bericht dat de pagina post zodra mermaid geladen en __renderMermaid gedefinieerd is, vóór het de renderwachtrij vrijgeeft (met een 10s-time-out-vangnet). Bevestigd: geen FWFEvaluateJavaScriptError meer, diagrammen renderen vanaf de eerste weergave, en de PDF-export is niet meer leeg. make check groen.

Restant apart getrackt in #886: erDiagram en gantt renderen nog niet (type-specifiek, stille fallback zonder <svg>; PDF toont voor ER foutief een pie-duplicaat) — dat staat los van de race (5 andere typen renderen wél).

**Opgelost — de echte oorzaak was een opstartrace, niet het Promise-marshalen.** Beeldkeuring met ingebouwde diagnostiek gaf de doorslag: de pagina meldt `MermaidRender DIAG: setup-ok mermaid=object render=function` — mermaid **laadt en rendert wél** op macOS-WKWebView. De `FWFEvaluateJavaScriptError`-renders vielen alle in een venster van ~70ms **vóór** `setup-ok`: `_bootstrapped=true` werd gezet zodra `loadHtmlString` resolvet (= laden gestart), waarna de wachtrij meteen `runJavaScript(window.__renderMermaid(...))` afvuurde — maar die functie wordt pas een tel later gedefinieerd wanneer het 3,4MB-pagina-script draait. (Aanvulling op de vorige analyse: `runJavaScript` negeert `javaScriptResultTypeIsUnsupported` juist, dus de fout was een échte JS-exceptie = functie nog niet gedefinieerd.) **Fix:** de dienst wacht nu op het `setup-ok`-bericht dat de pagina post zodra mermaid geladen en `__renderMermaid` gedefinieerd is, vóór het de renderwachtrij vrijgeeft (met een 10s-time-out-vangnet). Bevestigd: geen `FWFEvaluateJavaScriptError` meer, diagrammen renderen vanaf de eerste weergave, en de PDF-export is niet meer leeg. `make check` groen. **Restant apart getrackt in #886:** erDiagram en gantt renderen nog niet (type-specifiek, stille fallback zonder `<svg>`; PDF toont voor ER foutief een pie-duplicaat) — dat staat los van de race (5 andere typen renderen wél).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#882
No description provided.