fix(passkey): stop reporting a cancelled passkey prompt as an error - #2739
fix(passkey): stop reporting a cancelled passkey prompt as an error#2739innolope-dev wants to merge 1 commit into
Conversation
useZeroDev classifies a WebAuthn failure, captures the raw error with full context, and throws a curated PasskeyError for display. For a plain user cancel it deliberately captures nothing on web — "Cancel saved no state". Four call sites undid that: - InvitesPage fired `void handleLoginClick()` with no catch, so cancelling the prompt became an unhandled rejection. Now caught, and the curated message is surfaced the way every other login entry point surfaces it. - GuestLoginModal console.error'd the wrapper, which captureConsoleIntegration turns into an event. - Landing and JoinWaitlist called Sentry.captureException on the wrapper — a second, context-free copy of an error already reported at the throw site, and the reason LOGIN_CANCELED showed up at error level at all. Landing and JoinWaitlist still report anything that isn't a PasskeyError, so an unexpected failure in the login path is not silenced. PEANUT-UI-QRW and PEANUT-UI-R20: 19 events yesterday, all expected outcomes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
Included review availability: 3 reviews are currently available. Based on recent review activity, included reviews refill at 5 per hour. 📝 WalkthroughWalkthroughLogin failure handling now shows feedback in the guest login and invites flows. Setup views avoid duplicate Sentry reports for ChangesLogin error handling
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change prevents expected passkey cancellations from being reported as errors while preserving user messaging and unexpected-error reporting; no actionable merge-blocking risk remains after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
Code-analysis diffPainscore total: 7167.28 → 7168 (+0.72) 🆕 New findings (24)
…and 4 more. ✅ Resolved (24)
…and 4 more. |
|
@coderabbitai review |
|
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
The intent that was being undone
useZeroDev.handleLoginalready does the right thing. It classifies the raw WebAuthn failure, captures it with full context, and throws a curatedPasskeyErrorcarrying user-facing copy. For a plain user cancel it captures nothing on web:Four call sites then reported the wrapper anyway, which is why
PEANUT-UI-R20— "Login was cancelled, or no passkey was found on this device" — exists at error level despite that deliberate silence.What changed
InvitesPagevoid handleLoginClick(), no catch → unhandled rejection on every cancelGuestLoginModalconsole.error(e)→captureConsoleIntegrationeventLandingSentry.captureException(wrapper)PasskeyErrorJoinWaitlistSentry.captureException(wrapper)PasskeyErrorThe guard is a named helper in
webauthn.utils.tsrather than four inline checks, and it's narrow —LandingandJoinWaitliststill report anything that isn't aPasskeyError, so an unexpected failure in the login path is not silenced. PostHog'sSIGNUP_LOGIN_ERRORis untouched: a failed login is still a funnel event, just not a crash report.Note on
InvitesPageThat one is a real bug independent of Sentry — a floating promise with no rejection handler. It previously showed the user nothing at all on failure; it now shows the curated message, consistent with
Landing,SetupPasskeyandJoinWaitlist.Verification
src/components/Invites: 61 passed, 1 failed — identical to thedevbaseline. The one failure isbadge-campaign-context.test.ts › source-qualifies every published content UTM, which reads@/content/generated/…and fails in any worktree without thesrc/contentsubmodule initialised. Confirmed pre-existing by re-running with this change reverted.src/components/Setup,GuestLoginModal,webauthn: 8 passed, 0 failed.tsc --noEmit: 231 errors, zero in any touched file — 229 are missing@/assets/*declarations in a fresh worktree, 2 are the samesrc/contentsubmodule.prettier --check: clean.InvitesPage.test.tsxgained auseToastmock alongside the existinguseLoginone, since the suite rendersInvitePageContentoutside aToastProvider.Related
#2735 adds
PasskeyErrorto thealreadyReportedbeforeSend list as a backstop, so a future call site can't reintroduce this. This PR removes the reports at source; that one stops them arriving if it happens again.Correction to the commit message
The commit says "PEANUT-UI-QRW and PEANUT-UI-R20: 19 events yesterday". The accurate figure is 13/day — QRW 9 + R20 4.
The extra 6 was
PEANUT-UI-SFV("No matching passkey was found"), which this PR does not fix. SFV is the raw Android error captured at the throw site inuseZeroDev, not thePasskeyErrorwrapper, so none of the four call-site changes touch it. It's arguably also an expected outcome (no passkey enrolled on this device) and worth reclassifying toLOGIN_CANCELED, but that changes user-facing copy and belongs in its own change.peanut-ui blocks force-push, so the commit message stands as written.
Summary by CodeRabbit
Bug Fixes
Tests