fix(sentry): stop dropping the errors behind "contact support" on sends - #2738
Merged
Conversation
A user hit the generic 'contact support' toast on a $1 send and the failure left no trace in Sentry, PostHog, or the backend. Native reporting works — her device delivered six events twenty minutes earlier — but nothing in the send path could produce a report: - The only Sentry path was console.error in handleSendUserOpEncoded picked up by captureConsoleIntegration. beforeSend then dropped it: viem's HttpRequestError carries 'Details: Failed to fetch', which the networkIssues filter matches. Zero such events exist org-wide in 14 days, so the filter is absolute — it eats real payment failures along with the noise. - The flow-level catch mapped the error to copy and stopped there. No captureException, no analytics; capturePasskeySignFailure returns early for everything that isn't a WebAuthn DOMException. - The native init has no offline transport, so a WebView that can't reach the bundler can't deliver the report of that failure either. Tag explicit captures from money-moving flows and exempt them from the noise filters (cancellations stay filtered), report the direct-send failure at the flow level with the step and charge id, and buffer native envelopes to IndexedDB so they flush on a later launch.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ 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:
Comment |
Contributor
Code-analysis diffPainscore total: 7167.28 → 7170.08 (+2.8) 🆕 New findings (11)
✅ Resolved (11)
📈 Painscore deltas (top movers)
|
Contributor
🧪 UI test report — ✅ all greenSuites
📊 Coverage (unit)
⏱ 10 slowest test cases
|
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.
Why
A user hit the generic "There was an issue with your request. Please contact support." toast on a $1 send. The failure left no trace: nothing in the backend (every request from her IP was 2xx), nothing on chain (no UserOperation), nothing in PostHog, nothing in Sentry.
Native reporting itself is fine — her device (
environment:native, release60e0e52= mobile-release 1.0.43) delivered 6 Sentry events 20 minutes before the failed send, and native produces ~980 events/day. The blind spot is specific to the send path:handleSendUserOpEncodeddoesconsole.error('Error sending UserOp:', error)and only callscaptureExceptionon the stale-webauthn-key branch;capturePasskeySignFailurereturns early for anything that isn't a WebAuthnDOMExceptionand posts to PostHog only. So the report depended entirely oncaptureConsoleIntegration.beforeSendthen deleted it. viem'sHttpRequestErrormessage carriesDetails: Failed to fetch, which thenetworkIssuesfilter matches. Zero events matchingFailed to fetch/Load failed/Network Errorexist org-wide in the last 14 days, across every environment — the filter is absolute, and it eats real payment failures along with the noise. The same string is why the UI said "contact support":friendlyErrordoesn't map it either, so it falls through togenericSupport.ingest.us.sentry.ioeither, so even an unfiltered event died with the session.What changed
src/utils/sentry-critical-flow.ts(new) —CRITICAL_FLOW_TAG+criticalFlowTags(flow). Its own module because the rootsentry.utils.tsis loaded by the server and edge configs and must not reach into app-layer code.sentry.utils.ts— events carrying the tag skip the noise filters. User cancellations stay filtered even for tagged events: someone backing out of the passkey sheet is not a defect and would drown out the real failures.useDirectSendFlow.ts— the catch now reports:captureExceptionwith the failing step (create-charge/send-money/record-payment), charge id, recipient, amount and user id, plus asend_failedPostHog event. Every "contact support" toast now leaves one queryable record.instrumentation-client.ts— native init usesmakeBrowserOfflineTransport, so undeliverable envelopes park in IndexedDB and flush on a later launch.sentry.utils.test.ts— covers the exemption and the cancellation carve-out.Notes / follow-ups
UserOperationExecutionError), the console-capture event and the new explicit capture will both fire and group separately. I left theconsole.errorin place deliberately —handleSendUserOpEncodedis also called from link creation, kernel migration and card-signature repair, none of which capture explicitly, so suppressing it globally would lose coverage there.withdraw/crypto,qr-payand the contribute-pot flow have the same shape (catch → friendly copy → silence) and should get the same treatment; happy to do them in a follow-up or fold them in if you'd rather have one pass.Testing
jest sentry.utils.test.ts— 49 passed.prettier --checkclean on all touched files;tsc --noEmitreports no errors in the touched files.