enhancement
major
minor
major
minor
minor
#30056
TL Views: NullPointerException in ReactControl.commitUpdate from the session-timeout notice countdown ("Failed to announce the activity of session")
Problem
Snapshot build 59 (2026-10-29), TL Development app, logged in as root while a project board was opening. ReactWindowRegistry logged an ERROR "Failed to announce the activity of session" with a NullPointerException:
- ReactControl.commitUpdate (line 1076) receives a null patch,
- called from ReactNoticeBarControl.show (line 248),
- called from SessionTimeoutNoticeElement$Countdown.update (line 250).
It is the only ERROR of the session.
Expected
The countdown of the session-timeout notice never runs into a missing patch. Either the notice bar builds its update before committing it, or commitUpdate treats "nothing to send" as a no-op.
Test
Configure a short session timeout so the notice countdown runs while a page with many controls is being built: no ERROR in the log.
Lösung
Ursache ist eine Race-Condition, kein fehlender Patch: Der SessionActivityFilter meldet jeden Request der Sitzung (auch Stylesheets und Requests anderer Fenster) über ReactWindowRegistry.noteActivity an die Aktivitäts-Listener. Der Countdown des Sitzungsablauf-Hinweises änderte daraufhin die Hinweisleiste ohne die Interaction-Sperre der Sitzung, während der Request-Thread des Fensters denselben Kontrollbaum aufbaute. Ein beginUpdate im fremden Thread sah den offenen Batch des anderen Threads, erhielt das Token eines geschachtelten Aufrufs (null) und stieß nach dessen Commit in commitUpdate(null) auf den bereits zurückgesetzten Patch.
- Aktivitäts-Listener laufen nur noch innerhalb einer Interaction der Sitzung. noteActivity merkt sich die jüngste Aktivität und meldet sie sofort, wenn die Sperre frei ist (tryBeginInteraction(0)) - ohne zu warten, da der Filter auch Stylesheets und fremde Servlets abdeckt.
- Hält ein anderer Thread die Interaction, meldet dieser die vorgemerkte Aktivität beim Schließen seiner äußersten Interaction, so dass der Patch mit den übrigen Updates dieser Interaction ausgeliefert wird. Nach dem Freigeben der Sperre wird erneut geprüft, damit keine zwischenzeitlich vorgemerkte Aktivität verloren geht.
- ReactControl.commitUpdate bleibt unverändert: eine Null-Prüfung dort würde die Race-Condition nur verdecken.