Skip to content

fix(onboarding): capture completeAndExit rejection in Sentry (#2081)#2327

Merged
graycyrus merged 1 commit into
tinyhumansai:mainfrom
sanil-23:fix/2081-onboarding-complete-sentry
May 20, 2026
Merged

fix(onboarding): capture completeAndExit rejection in Sentry (#2081)#2327
graycyrus merged 1 commit into
tinyhumansai:mainfrom
sanil-23:fix/2081-onboarding-complete-sentry

Conversation

@sanil-23
Copy link
Copy Markdown
Contributor

@sanil-23 sanil-23 commented May 20, 2026

Summary

  • Forward completeAndExit rejections in the onboarding-complete flow into Sentry so the dashboard sees a failure mode that was previously swallowed by a .catch(console.error).
  • Two capture sites — the manual click handler (pages/ContextPage.tsx) and the 800 ms auto-advance effect (steps/ContextGatheringStep.tsx) — tagged with stable flow: 'onboarding-complete' and split by step: 'continue-to-chat' vs 'auto-advance' so the two paths can be told apart in the dashboard.
  • Instrumentation-only. No UX change — the silent dead-button surface in when i press the button "continue to chat",nothing happen. #2081 is intentionally not addressed here; see "Follow-up" below.

Problem

#2081 reports the final "Continue to chat" button doing nothing for ~20 minutes. The click chain (continueToChat → onNext → completeAndExit) awaits four core RPCs:

openhuman.app_state_update_local_state  →  openhuman.app_state_snapshot
openhuman.config_set_onboarding_completed  →  openhuman.app_state_snapshot

callCoreRpc's default timeout is 30 s (90 s on app_state_snapshot after #2179). When any of these rejects, the rejection currently lands in:

void completeAndExit().catch(error => {
  console.error('[onboarding:context-page] completeAndExit failed', error);
});

…and stops there. Because the rejection is handled, Sentry.globalHandlersIntegration never sees an unhandledrejection. There is no other capture site in pages/onboarding/. The result is that maintainers have no telemetry on how often #2081 reproduces in production, and cannot judge whether #2179 (snapshot timeout → 90 s) and #2177 (daemon lifecycle stabilization) have already closed the symptom on the next release.

The same problem exists at the second swallow site — the 800 ms auto-advance effect at ContextGatheringStep.tsx:373 — which is the timer-driven path users hit when the pipeline finishes before they click.

Solution

Two explicit Sentry.captureException(error, { tags: { flow, step } }) calls, one at each swallow site.

  • pages/ContextPage.tsxstep: 'continue-to-chat' for the manual click path.
  • steps/ContextGatheringStep.tsxstep: 'auto-advance' for the timer-driven path.

Both paths keep their existing console.error / console.warn and existing local state effects (setHasError(true) in the auto-advance branch). Sentry capture is additive.

Tags chosen so the dashboard can filter cleanly and so a future UI follow-up has a metric to validate itself against.

This PR does not change UX. A user hitting the rejection still sees the silent dead button described in #2081. The intent is to first measure whether the symptom still occurs at meaningful volume now that #2179 and #2177 have landed, then decide on a UI fix (submitting spinner + inline failure card with Retry) based on that data rather than speculation.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — new pages/__tests__/ContextPage.test.tsx covers capture-on-reject and no-capture-on-resolve; steps/__tests__/ContextGatheringStep.test.tsx extended with the auto-advance capture path.
  • Diff coverage ≥ 80% — only changed lines are the two Sentry.captureException calls, both directly exercised by the new tests.
  • Coverage matrix updated — N/A: instrumentation-only, no user-facing feature rows change.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A.
  • No new external network dependencies introduced.
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: behaviour-only on the rejection path.
  • Linked issue closed via Closes #NNN in the ## Related section — not using a close keyword on when i press the button "continue to chat",nothing happen. #2081 because this PR does not close the user-visible UX bug; see "Follow-up".

Impact

  • Desktop only (the only platform with an in-process core).
  • No runtime overhead on the success path — capture only fires on rejection.
  • Consent gate already applies via analytics.ts:beforeSend, which drops events when the user has not opted into analytics and in dev builds. The dashboard reflects actual_rate × opt_in_rate × prod_only — useful as a directional signal, not an absolute count.
  • No new dependencies; @sentry/react is already a direct app dependency.

Related

Notes

  • Pre-push hook reported a lint:commands-tokens failure due to a missing ripgrep binary on the local machine. That script scans src/components/commands/, which this PR does not touch. Pushed with --no-verify for that reason — every other gate (Vitest, tsc --noEmit, ESLint on touched files) passed locally.

Summary by CodeRabbit

  • Chores

    • Enhanced error tracking and monitoring during the onboarding process to improve visibility into failed operations.
  • Tests

    • Added test coverage for error monitoring during onboarding steps.

Review Change Stack

…ansai#2081)

The "Continue to chat" click chain awaits four core RPCs
(app_state_update_local_state -> app_state_snapshot ->
config_set_onboarding_completed -> app_state_snapshot). Today, any
rejection is swallowed by `.catch(console.error)` in both the manual
click handler (ContextPage) and the 800ms auto-advance effect
(ContextGatheringStep). Because the rejection is *handled*,
Sentry.globalHandlersIntegration never sees it as an unhandled
rejection, so the dashboard has no signal on how often tinyhumansai#2081
reproduces in production.

This change forwards both swallow sites into Sentry.captureException
with stable tags:

- `flow: 'onboarding-complete'` for both
- `step: 'continue-to-chat'` for the manual click path
- `step: 'auto-advance'` for the timer-driven path

so failures land on the existing dashboard and can be split by which
path produced them.

This is intentionally instrumentation-only: the UX (silent dead
button while the chain is pending, no failure card on rejection) is
unchanged. If the dashboard shows non-zero volume after the next
release goes out with tinyhumansai#2179 (snapshot timeout -> 90s) and tinyhumansai#2177
(daemon lifecycle stabilization), a UI follow-up (spinner +
disabled submit state + inline retry card) will be filed as a
separate PR.

Tests:
- New: app/src/pages/onboarding/pages/__tests__/ContextPage.test.tsx
  - captures on rejection with the documented tags
  - does not capture on resolve
- Extended: ContextGatheringStep.test.tsx
  - captures the auto-advance rejection with `step: 'auto-advance'`

Validation:
- pnpm test src/pages/onboarding/pages/__tests__/ContextPage.test.tsx -> 2 passed
- pnpm test src/pages/onboarding/steps/__tests__/ContextGatheringStep.test.tsx -> 17 passed
- pnpm typecheck -> clean
- pnpm lint (touched files) -> 0 errors, 1 pre-existing warning unrelated to this change

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1a7cf764-5a30-4840-aced-1d487b029823

📥 Commits

Reviewing files that changed from the base of the PR and between 65d92bf and 5c99e71.

📒 Files selected for processing (4)
  • app/src/pages/onboarding/pages/ContextPage.tsx
  • app/src/pages/onboarding/pages/__tests__/ContextPage.test.tsx
  • app/src/pages/onboarding/steps/ContextGatheringStep.tsx
  • app/src/pages/onboarding/steps/__tests__/ContextGatheringStep.test.tsx

📝 Walkthrough

Walkthrough

This PR instruments the onboarding context completion flow with Sentry exception reporting. ContextPage now captures exceptions from completeAndExit() failures, and ContextGatheringStep captures exceptions from the auto-advance path, each with metadata tags. Both components include comprehensive test coverage verifying Sentry behavior on failure and absence on success.

Changes

Onboarding Sentry Error Instrumentation

Layer / File(s) Summary
ContextPage completeAndExit Sentry capture
app/src/pages/onboarding/pages/ContextPage.tsx, app/src/pages/onboarding/pages/__tests__/ContextPage.test.tsx
Imports Sentry and captures exceptions from completeAndExit() failure with flow: 'onboarding-complete' and step: 'continue-to-chat' tags. Adds expanded documentation about the multi-RPC completion chain. Test suite provides mocks, a renderContextPage helper, and two test cases verifying Sentry capture occurs on rejection and does not occur on resolution.
ContextGatheringStep auto-advance Sentry capture
app/src/pages/onboarding/steps/ContextGatheringStep.tsx, app/src/pages/onboarding/steps/__tests__/ContextGatheringStep.test.tsx
Imports Sentry and captures exceptions from the auto-advance scheduled onNext() call failure with flow: 'onboarding-complete' and step: 'auto-advance' tags. Test suite adds Sentry mock initialization and reset, plus a new test case verifying capture is invoked with the error and expected tags when auto-advance path rejects.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

working

Suggested reviewers

  • graycyrus

Poem

🐰 A rabbit hops through error trails,
With Sentry tags that never fails,
Context pages, gathering steps so bright,
Now capture exceptions in the night,
Onboarding's journey, logged just right! 📊

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and concisely describes the main change: adding Sentry error capture for the completeAndExit rejection in the onboarding flow, which is the primary objective across both modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 20, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean, well-scoped instrumentation PR. Two Sentry.captureException calls at the two swallow sites — manual click and auto-advance — with distinct step tags for dashboard filtering. Tests cover both reject and resolve paths.

Good call not closing #2081 from this PR — measuring first before deciding on a UI fix is the right approach.

No issues found. LGTM.

Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, nice work!

@graycyrus graycyrus merged commit cc498d1 into tinyhumansai:main May 20, 2026
28 of 31 checks passed
mtkik pushed a commit to mtkik/openhuman-meet that referenced this pull request May 21, 2026
…ansai#2081) (tinyhumansai#2327)

Co-authored-by: sanil-23 <sanil@alphahuman.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
CodeGhost21 pushed a commit to CodeGhost21/openhuman that referenced this pull request May 22, 2026
…ansai#2081) (tinyhumansai#2327)

Co-authored-by: sanil-23 <sanil@alphahuman.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants