Skip to content

iOS: network error events from JS-tracked requests bypass the drop_resource deduplication and cannot be filtered — expose a native error mapper? #1338

Description

@LinFeiLong

Feature description

Use case

Our React Native app (restaurant-facing B2B, devices often on flaky Wi-Fi) generates a high volume of RUM network error events on iOS for requests that are already tracked by the JS layer. Over 30 days we measured ~583k such error events (29% of all our error events), which pollute Error Tracking, distort iOS-vs-Android comparisons, and retain sessions via error-based retention filters.

How the SDK currently behaves

On iOS, a request made from JS is tracked twice: by the JS XHRProxy and by the native URLSession instrumentation. The SDK deduplicates this elegantly for resources and actions: the JS layer tags its requests, resourceAttributesProvider marks the native events with _dd.resource.drop_resource: true, and the native resourceEventMapper / actionEventMapper registered in DdSdkNativeInitialization.swift drop them.

However, when such a request fails, dd-sdk-ios emits an error event for it — and no errorEventMapper is registered, so the event always reaches Datadog even though it still carries the _dd.resource.drop_resource marker in its context. We verified in our production data that 100% of these error events carry the marker.

Two consequences:

  1. Platform inconsistency: on Android, a failed JS-tracked request produces no error event at all (the RN SDK does not register an equivalent native network instrumentation there by default). The same network failure therefore produces different data depending on the platform.
  2. No way to filter: these events are generated natively, so the JS errorEventMapper from DatadogProviderConfiguration never sees them, and no native hook is exposed. Application code has no supported way to drop or transform them.

What we would like to see

A supported way to control these native network error events — for example:

  • a native errorEventMapper in RUM.Configuration that drops events carrying the drop_resource marker (consistent with the existing resource/action mappers, and aligning iOS on the current Android behavior), possibly opt-in if you consider the current behavior intentional; and/or
  • routing these error events through the JS errorEventMapper so applications can decide.

Proposed solution

Mirroring the two existing mappers in DdSdkNativeInitialization.swift:

errorEventMapper: { errorEvent in
    if errorEvent.context?.contextInfo[InternalConfigurationAttributes.dropResource]
        != nil
    {
        return nil
    }
    return errorEvent
},

We are currently running this as a patch-package patch on @datadog/mobile-react-native@3.4.0: it builds and removes exactly the marked duplicates, while error events from natively-issued requests (which have no JS mirror) are untouched. Happy to open a PR (with signed commits) if this — or an opt-in variant — is a direction you would accept.

Other relevant information

  • Observed on @datadog/mobile-react-native 3.4.0; the code path is unchanged on develop as of today.
  • The failure information itself is not lost when dropping these events: the JS layer still reports the resource with status_code: 0.
  • The dominant traffic in our case is a third-party SDK (Amplitude Experiment) retrying fetches on unstable networks, but any JS-tracked host is affected, including our own APIs.
  • Example event context (production, RN 0.79 / RUM iOS 3.11): error event with error.source: network, error.resource.* set, and context._dd.resource.drop_resource: true.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions