fix: telemetry dropped by user callbacks and by validation is now counted in client reports - #5607
jamescrosswell wants to merge 6 commits into
Conversation
Work item 2 of #5535. Items lost to a user callback — whether it returned null or threw — were disappearing without a client report, and a throwing event or transaction processor skipped the report entirely by unwinding to the Hub catch-all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## fix/isolate-user-callbacks #5607 +/- ##
==============================================================
+ Coverage 74.90% 74.96% +0.06%
==============================================================
Files 515 515
Lines 18966 18993 +27
Branches 3696 3698 +2
==============================================================
+ Hits 14206 14238 +32
+ Misses 3878 3874 -4
+ Partials 882 881 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Let's do that in this PR as well... no reason to do it in a follow up (the size of the PR is still manageable). |
A log whose template doesn't match its arguments, and a metric with an unsupported value type or an empty name, were dropped with a diagnostic log and no client report. Records the spec's `invalid` reason, which the SDK did not previously carry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every other deliberate drop by a user callback logs at info level naming the callback; logs and metrics were the exception. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dd74bf4 to
7710900
Compare
… fix/callback-client-reports
ric-oliv
left a comment
There was a problem hiding this comment.
Hi @jamescrosswell, the hooks spec was revised today (getsentry/sentry-docs#19189, b53c3009) 😅
A callback that throws must now be reported with the callback_error discard reason, so users can tell a failure apart from an explicit drop.
The catch blocks in this PR now need to record callback_error instead of before_send / event_processor. null returns stay as they are. callback_error is already in the stable client reports spec, so we just need a new DiscardReason here.
Same in the throw paths in #5610.
Follows the hooks spec revision in getsentry/sentry-docs#19189 (b53c3009): a throwing callback must be distinguishable from an explicit drop, so every item a failure drops is recorded as callback_error with the item's category. Null returns keep their existing reasons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GitHub stopped rebuilding refs/pull/5607/merge, so no pull_request workflow could be created and the PR reported a conflict that git shows does not exist. A new head commit forces the ref to be recomputed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Work item 2 ("emit the missing client reports") of #5535, plus the adjacent validation drops in the same files. Stacked on #5606 — review that one first; this branch targets
fix/isolate-user-callbacksand the diff here is only the five source files below.The spec is explicit that "isolating a callback without reporting the loss is a conformance failure". Twelve drop paths were losing telemetry with no client report at all, so a user filtering or mis-calling these APIs saw nothing in their org's client reports.
Callback failures (work item 2)
BeforeSendLogreturnsnull/ throwsbefore_send/log_itemconfigureLogthrowsbefore_send/log_itemBeforeSendMetricreturnsnull/ throwsbefore_send/trace_metricevent_processor+ the caller's category, event droppedevent_processor/transaction+span, transaction droppedThese match the hooks spec matrix exactly:
before_send_log→before_send/log_item,before_send_metric→before_send/trace_metric. Note the spec forbids thecallback_errorreason here — "A dropped item MUST be reported exactly as it is on an explicit drop, and MUST NOT use a reason the callback could not otherwise produce" — so a throwing callback is deliberately indistinguishable from a deliberate drop.Validation drops (adjacent, same files)
FormatException)invalid/log_itemCaptureMetricoverloads)invalid/trace_metricinvalid/trace_metricinvalid— "Failed validation" — is in the client reports spec but was one of six reasons the SDK'sDiscardReasondidn't carry; this adds it. Relay accepts it:DiscardedEvent.reasonis a free-formString, anddiscarded_eventsmaps toOutcome::ClientDiscard(reason.into())with no allowlist (relay-server/src/processing/client_reports/process.rs). Conversion is per-outcome, so an unrecognised reason could never take a whole report down.Notes for review:
SentryEventHelper.ProcessEventalready recordedevent_processorwhen a processor returned null; a processor that threw jumped straight past that branch toHub.CaptureEvent's catch-all, which records nothing and logs"Failure to capture event"— naming the capture rather than the processor. This is precisely the trap the Linear write-up calls out. The per-processor catch now records the discard and names the processor.SentryClient.CaptureTransactionhas the identical defect against the identical catch-all, and the spec requirement is the same.configureLogisn't in the spec matrix (it's theAction<SentryLog>overload parameter, already marked "will be removed in a future version"). It can't deliberately drop a log, so there's no "same report a deliberate drop would produce" to copy —before_send/log_itemis the closest fit.BeforeSend/BeforeSendTransactionalignment) of Conform to the callback error isolation spec (wrap all user callbacks) #5535 is still open, so this doesn't close the issue.🤖 Generated with Claude Code