Skip to content

♻️ Route fetch, XHR, and console through bufferedDataObservable#4470

Merged
thomas-lebeau merged 7 commits intov7from
thomas.lebeau/unify-buffered-observables
Apr 15, 2026
Merged

♻️ Route fetch, XHR, and console through bufferedDataObservable#4470
thomas-lebeau merged 7 commits intov7from
thomas.lebeau/unify-buffered-observables

Conversation

@thomas-lebeau
Copy link
Copy Markdown
Collaborator

Motivation

Centralize the buffering of fetch, XHR, and console observables into bufferedDataObservable instead of each observable managing its own buffer. This simplifies the pre-start data flow and removes the need for early instrumentation (subscribe(noop)) and product-specific wrappers like trackConsoleError.

Changes

  • Add FETCH, XHR, and CONSOLE types to the BufferedData discriminated union with a consistent { type, data } shape
  • Subscribe to fetch/xhr/console observables in startBufferingData() so buffering is centralized
  • Update Logs and RUM consumers to receive network and console events via bufferedDataObservable instead of subscribing directly to each observable
  • Convert fetchObservable/xhrObservable/consoleObservable from BufferedObservable to plain Observable (buffering now centralized)
  • Remove early instrumentation (subscribe(noop)) from pre-start phases
  • Remove trackConsoleError (replaced by console handling in errorCollection)

Test instructions

  • Run yarn test:unit to verify all unit tests pass
  • Verify that fetch, XHR, and console errors are still collected correctly during pre-start and post-start phases

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/unify-buffered-observables branch from e98e9d5 to 629186b Compare April 10, 2026 14:52
@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented Apr 10, 2026

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 167.99 KiB 168.22 KiB +231 B +0.13%
Rum Profiler 6.09 KiB 6.09 KiB 0 B 0.00%
Rum Recorder 27.10 KiB 27.10 KiB 0 B 0.00%
Logs 53.80 KiB 53.80 KiB -4 B -0.01%
Rum Slim 126.36 KiB 126.58 KiB +222 B +0.17%
Worker 22.99 KiB 22.99 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base CPU Time (ms) Local CPU Time (ms) 𝚫%
addglobalcontext N/A 0.0042 N/A
addaction N/A 0.0184 N/A
adderror N/A 0.0161 N/A
addtiming N/A 0.0031 N/A
startview N/A 0.0157 N/A
startstopsessionreplayrecording N/A 0.0007 N/A
logmessage N/A 0.0155 N/A
🧠 Memory Performance
Action Name Base Memory Consumption Local Memory Consumption 𝚫
addglobalcontext N/A 38.56 KiB N/A
addaction N/A 63.47 KiB N/A
addtiming N/A 40.88 KiB N/A
adderror N/A 69.23 KiB N/A
startstopsessionreplayrecording N/A 40.08 KiB N/A
startview N/A 476.87 KiB N/A
logmessage N/A 57.73 KiB N/A

🔗 RealWorld

@datadog-datadog-prod-us1-2
Copy link
Copy Markdown

datadog-datadog-prod-us1-2 Bot commented Apr 10, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 79.79%
Overall Coverage: 77.50% (-0.03%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f7feeaa | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/unify-buffered-observables branch from 629186b to 496df82 Compare April 13, 2026 05:45
- Add FETCH, XHR, and CONSOLE types to BufferedData discriminated union
- Subscribe to fetch/xhr/console observables in startBufferingData()
- Update Logs and RUM consumers to receive network and console events
  via bufferedDataObservable instead of subscribing directly
- Remove early instrumentation (subscribe(noop)) from preStart phases
- Remove trackConsoleError (replaced by console handling in errorCollection)
- Convert fetchObservable/xhrObservable/consoleObservable from
  BufferedObservable to plain Observable (buffering now centralized)
- Normalize BufferedData shape to use { type, data } consistently
@thomas-lebeau thomas-lebeau force-pushed the thomas.lebeau/unify-buffered-observables branch from 496df82 to 27309cc Compare April 13, 2026 10:31
…romRawError

- Remove redundant fingerprint, causes, and dd_context tests from
  consoleCollection.spec.ts since error field construction is already
  tested in createErrorFieldFromRawError.spec.ts
- Add actual cause entries in createErrorFieldFromRawError tests to
  cover the cases previously tested in consoleCollection
- Rename remaining console test to clarify its purpose
- Verify responseBody is undefined when bodyUsed is true
- Verify responseBody is undefined when bodyDisturbed is true
Due to FIFO subscriber ordering on singleton observables, the
bufferedDataObservable subscriber and the direct subscriber fire in
different orders depending on the SDK lifecycle phase. assignRequestIndex
ensures the first caller wins, keeping REQUEST_STARTED and
REQUEST_COMPLETED requestIndex values consistent.
@thomas-lebeau thomas-lebeau marked this pull request as ready for review April 14, 2026 08:43
@thomas-lebeau thomas-lebeau requested a review from a team as a code owner April 14, 2026 08:43
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3d96224bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

})
})
subscribe(BufferedDataType.RUNTIME_ERROR, mockable(trackRuntimeError)())
subscribe(BufferedDataType.FETCH, initFetchObservable())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Defer fetch buffering until fetch instrumentation can attach

startBufferingData() now subscribes to initFetchObservable() immediately, which makes this the first (and long-lived) subscriber. In createFetchObservable(), instrumentation is only installed when globalObject.fetch exists at first subscribe time; if a fetch polyfill is loaded later (common in older browsers), the early subscription never retries and fetch events are never collected for the rest of the session. Before this commit, the first fetch subscription happened during init(), so late-loaded polyfills could still be instrumented.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid but narrow — this only affects browsers without native fetch that load a polyfill after SDK load but before init().

Sincerely yours, Claude

})
subscribe(BufferedDataType.RUNTIME_ERROR, mockable(trackRuntimeError)())
subscribe(BufferedDataType.FETCH, initFetchObservable())
subscribe(BufferedDataType.XHR, initXhrObservable({ allowUntrustedEvents: true }))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve configured untrusted-event filtering for XHR

Initializing XHR buffering with allowUntrustedEvents: true hard-codes the global XHR observable to accept untrusted events, because initXhrObservable() is singleton-based and keeps the first configuration. This bypasses user configuration where allowUntrustedEvents is false, so synthetic loadend events can now be processed and may generate incorrect or attacker-controlled request completions that were previously filtered.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User config isn't available pre-init(), so we default to allowUntrustedEvents: true. This is low risk while covering edge cases with some XHR polyfills.

Sincerely yours, Claude

Comment thread packages/core/src/browser/fetchObservable.ts Outdated
Comment thread packages/core/src/browser/xhrObservable.ts Outdated
- Build notification objects inline instead of mutating context in fetch error handler
- Replace shallowClone with spread operator in XHR observable notification
@thomas-lebeau thomas-lebeau merged commit 68357e1 into v7 Apr 15, 2026
20 checks passed
@thomas-lebeau thomas-lebeau deleted the thomas.lebeau/unify-buffered-observables branch April 15, 2026 05:38
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants