Repository navigation
iOS native events dropped by managed callbacks are counted twice in client reports #5681
Description
Part of #5634.
Branch: main. No public API change, so this doesn't need to wait for v7.
On iOS, ProcessOnBeforeSend runs the managed event processors and BeforeSend on native events:
sentry-dotnet/src/Sentry/Platforms/Cocoa/SentrySdk.cs
Lines 315 to 321 in f55e72e
| if (SentryEventHelper.ProcessEvent(sentryEvent, manualProcessors, null, options, DataCategory.Error) | |
| is not { } processedEvent) | |
| { | |
| return null; | |
| } | |
| processedEvent = SentryEventHelper.DoBeforeSend(processedEvent, new SentryHint(), options); |
SentryEventHelper records the drop:
sentry-dotnet/src/Sentry/Internal/SentryEventHelper.cs
Lines 26 to 60 in f55e72e
| options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, dataCategory); | |
| options.LogError(e, "Event processor {0} threw an exception. The event will be dropped.", processor.GetType().Name); | |
| return null; | |
| } | |
| if (processedEvent == null) | |
| { | |
| options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, dataCategory); | |
| options.LogInfo("Event dropped by processor {0}", processor.GetType().Name); | |
| break; | |
| } | |
| } | |
| return processedEvent; | |
| } | |
| public static SentryEvent? DoBeforeSend(SentryEvent? @event, SentryHint hint, SentryOptions options) | |
| { | |
| if (@event is null || options.BeforeSendInternal is null) | |
| { | |
| return @event; | |
| } | |
| options.LogDebug("Calling the BeforeSend callback."); | |
| try | |
| { | |
| @event = options.BeforeSendInternal?.Invoke(@event, hint); | |
| if (@event == null) // Rejected event | |
| { | |
| options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.Error); | |
| options.LogInfo("Event dropped by BeforeSend callback."); | |
| } | |
| } | |
| catch (Exception e) | |
| { | |
| options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.CallbackError, DataCategory.Error); |
.NET then returns nil, and sentry-cocoa records before_send for the same event:
https://github.com/getsentry/sentry-cocoa/blob/9.29.2/Sources/Sentry/SentryClient.m#L1164-L1172
| Native event dropped because | .NET counts | sentry-cocoa counts |
|---|---|---|
Event processor returns null |
event_processor |
before_send |
| Event processor throws | callback_error |
before_send |
BeforeSend returns null |
before_send |
before_send |
BeforeSend throws |
callback_error |
before_send |
Main already double-counts a null return. For a throw, the two counts also disagree on the reason.
Approach
Skip the .NET record for native events, since sentry-cocoa already counts them (decision). Until sentry-cocoa can count callback_error (getsentry/sentry-cocoa#8993), a throw on a native iOS event only shows up as before_send.
Activity
linear-code commentedon Oct 7, 2026
NET-843