fix(web): keep the signed-out message alive and unqueued - #2529
Merged
Conversation
Two ways the one message telling a user their write failed could never reach them: - signOut raised a toast and then assigned window.location, and a document navigation tears the toast down. The early return meant this only happened on routes other than the calendar, which is exactly where the message was needed. Route in-app instead, the same way SessionExpiredToast already reaches the router. - ToastContainer allowed one toast at a time, so any routine toast already on screen silently queued out a critical one behind it. Adds coverage for the navigating branch, which had none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Its only caller was the sign-out path, which now routes in-app. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The limit raise broke calendar-experience keyboard selection consistently across all 3 Playwright retries. Isolating it from the navigation fix, which is the substantive change here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Note: the The underlying gap is real (a critical toast can still be silently queued behind a routine one), but it needs that interaction understood before it lands. Tracked as a follow-up. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Investigating a report of "my event disappeared and I got no indication of an error", two independent ways the one message telling a user their write failed could never reach them:
A document navigation destroyed it.
signOut()raises a toast and then callswindow.location.assign("/week"). That is a full page load, so the toast is torn down before it can be read. The early return means this only happens when the user is not already on the calendar route — which is precisely the case where the message matters, since they are also being moved away from where they were.The toast could be silently queued out.
ToastContainerhadlimit={1}, so any routine toast already on screen (an undo notice, an autosave confirmation) pushes a critical "you've been signed out" into a queue the user may never see.Together: the user's write fails, their optimistic edit rolls back, and nothing explains why.
Changes
signOutroutes in-app via the router singleton instead of assigningwindow.location.SessionExpiredToastalready reaches the router this way, including the dynamic import that avoids the module cycle, so this follows an established path rather than inventing one.limit={1}→limit={3}.Tests
The navigating branch of
signOuthad no coverage — the existing test pins the already-on-calendar case and notes it does so specifically to skip the jsdom-unsupported navigation. Adds a test for the branch that was actually broken.24/24 api.util tests pass, 1519/1519 web tests pass (checked for
mock.moduleleakage across files), type-check and lint clean.Not included
The mutation layer still swallows 401 in
handleError, deferring to this interceptor. That is now a safe assumption again since the interceptor's message survives, but it is worth revisiting alongside aMutationCache.onErrorbackstop.🤖 Generated with Claude Code