From 1dab858f14ca0cd67bf92762bb9bc347c516ab4e Mon Sep 17 00:00:00 2001 From: Aqil Aziz Date: Fri, 15 May 2026 11:06:25 +0700 Subject: [PATCH] fix(onboarding): keep skip completion moving after task sync failure (#1771) --- app/src/pages/onboarding/OnboardingLayout.tsx | 22 +++++++++++-------- .../__tests__/OnboardingLayout.test.tsx | 17 ++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/src/pages/onboarding/OnboardingLayout.tsx b/app/src/pages/onboarding/OnboardingLayout.tsx index c27b328b2..0a75b0846 100644 --- a/app/src/pages/onboarding/OnboardingLayout.tsx +++ b/app/src/pages/onboarding/OnboardingLayout.tsx @@ -65,15 +65,19 @@ const OnboardingLayout = () => { connectedSources: draft.connectedSources, }); - await setOnboardingTasks({ - accessibilityPermissionGranted: - snapshot.localState.onboardingTasks?.accessibilityPermissionGranted ?? false, - localModelConsentGiven: false, - localModelDownloadStarted: false, - enabledTools: getDefaultEnabledTools(), - connectedSources: draft.connectedSources, - updatedAtMs: Date.now(), - }); + try { + await setOnboardingTasks({ + accessibilityPermissionGranted: + snapshot.localState.onboardingTasks?.accessibilityPermissionGranted ?? false, + localModelConsentGiven: false, + localModelDownloadStarted: false, + enabledTools: getDefaultEnabledTools(), + connectedSources: draft.connectedSources, + updatedAtMs: Date.now(), + }); + } catch (e) { + console.warn('[onboarding] Failed to persist onboarding tasks; continuing completion', e); + } try { await userApi.onboardingComplete(); diff --git a/app/src/pages/onboarding/__tests__/OnboardingLayout.test.tsx b/app/src/pages/onboarding/__tests__/OnboardingLayout.test.tsx index e7ae9c3d2..be393e30b 100644 --- a/app/src/pages/onboarding/__tests__/OnboardingLayout.test.tsx +++ b/app/src/pages/onboarding/__tests__/OnboardingLayout.test.tsx @@ -228,4 +228,21 @@ describe('OnboardingLayout — Joyride walkthrough integration (#1123)', () => { // Navigation should still proceed even when the flag cannot be written. expect(screen.getByTestId('home-page')).toBeInTheDocument(); }); + + it('still completes onboarding when persisting onboarding tasks fails', async () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + const { mockSetOnboardingCompletedFlag, mockSetOnboardingTasks } = await setupLayout(); + mockSetOnboardingTasks.mockRejectedValueOnce( + new Error('Core RPC openhuman.app_state_snapshot timed out after 30000ms') + ); + + await act(async () => { + fireEvent.click(screen.getByTestId('complete-btn')); + }); + + expect(mockSetOnboardingCompletedFlag).toHaveBeenCalledWith(true); + expect(screen.getByTestId('home-page')).toBeInTheDocument(); + + warnSpy.mockRestore(); + }); });