Handle a null currentUser in homepage widgets
What does this MR do and why?
The homepage widgets read nested fields of currentUser in their Apollo update hooks. The GraphQL API returns currentUser: null when the request has no valid session. The hooks then throw, and the browser logs an uncaught TypeError. Under Vue 2 the widget stays blank. Under Vue 3 the render error in HomepageApp can take down the whole page.
This happens to a real user when the session expires while the homepage is open. When the tab gets focus again, the widgets refetch their data, and every request comes back with currentUser: null.
This MR treats a null currentUser as "no data" once, in each update hook. The widgets then render their empty state instead of throwing. The error handlers and the error states are not changed.
The change fixes these three browser console errors:
TypeError: Cannot read properties of null (reading 'assigned')inhomepage_app.vueTypeError: Cannot read properties of null (reading 'recentlyViewedItems')inrecently_viewed_items.vueTypeError: Cannot destructure property 'id' of '{}' as it is null.intodos_widget.vue
Ruled out
- The queries do not resolve with partial data before the network response.
vue-apolloonly callsupdatewhen the result has data. - A user without to-do items or recently viewed items gets an empty list, not a null
currentUser. Only a missing session makes the field null.
Follow-up
Once this MR and MR 256639 both merge, these three entries can be removed from spec/support/browser_console_allowlist.yml. All three list spec/features/users/login/regular_user_spec.rb:
TypeError: Cannot read properties of null (reading 'assigned')TypeError: Cannot read properties of null (reading 'recentlyViewedItems')TypeError: Cannot destructure property 'id' of '{}' as it is null.
How to verify
The errors are timing dependent in spec/features/users/login/regular_user_spec.rb. The session-expiry examples call expire_session while the homepage queries are still in flight in CI. Locally, the queries finish first, so the spec is green on master too.
A deterministic reproduction, run locally before and after the fix:
- Sign in and open the homepage.
- Expire the session in Redis (
expire_sessionfromSessionHelpers). - Dispatch two
visibilitychangeevents withDate.nowmoved forward by 10 seconds between them. This passes the widgets' debounce and makes them refetch.
Before the fix, the SEVERE browser log shows the three errors above. After the fix, it shows none of them. The login feature spec passes with an empty SEVERE console log.
Jest specs cover the state before the queries resolve and the state where they resolve with currentUser: null. They pass under yarn jest and VUE_VERSION=3 yarn jest. Without the fix, the two widget specs fail with the exact error messages, because the exception from update is rethrown from a timer that jest.runOnlyPendingTimers() flushes.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
References
- Allowlist entries surfaced by !256639 (merged)
- Console error catalogue #628901
- Pipeline that logged the errors https://gitlab.com/gitlab-org/gitlab/-/pipelines/2867610835
- Same bug class, DevOps adoption table rendering before data !255322 (merged)
- Same bug class, board list cache guard !255325 (merged)