Skip to content

fix(error-tracking): wait for debug ID injection before sourcemap upload - #487

Open
jhssilva wants to merge 1 commit into
DataDog:masterfrom
jhssilva:hugo.silva/rum-18038-artifacts-ready
Open

fix(error-tracking): wait for debug ID injection before sourcemap upload#487
jhssilva wants to merge 1 commit into
DataDog:masterfrom
jhssilva:hugo.silva/rum-18038-artifacts-ready

Conversation

@jhssilva

@jhssilva jhssilva commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What

Add an explicit artifacts-ready barrier so Error Tracking waits until esbuild finishes rewriting JavaScript and source-map artifacts before discovering sourcemaps and extracting debug IDs.

The early esbuild build-report callback queues the gated upload instead of blocking the later injection callback. Concurrent lifecycle attempts share one upload promise.

Why

RUM-18038 live testing showed esbuild uploaded all sourcemaps but extracted debug IDs for 0/N because upload ran before debug-ID injection completed.

How it works

  1. The RUM plugin generates a deterministic debug ID and requests its injection into each JavaScript chunk.
  2. The injection plugin writes the debug-ID snippet into the bundle and regenerates the sourcemap so generated locations still map to the correct original source.
  3. Error Tracking waits until every rewritten .js and .map artifact is ready.
  4. The uploader reads the final JavaScript, extracts the already-injected ddDebugId, and uploads that value with the final JavaScript and sourcemap.

The uploader does not inject or modify the bundle. The synchronization prevents it from reading or uploading artifacts while esbuild is still rewriting them.

Tests

  • 383 focused unit/integration tests passed
  • Core, factory, injection, and Error Tracking typechecks passed
  • ESLint passed
  • Regression test verifies every split esbuild JavaScript output has an extractable debug ID when upload starts
  • Existing injection E2E coverage verifies that adding a banner preserves the original source location through the regenerated sourcemap

Jira: https://datadoghq.atlassian.net/browse/RUM-18038

@jhssilva
jhssilva marked this pull request as ready for review August 14, 2026 08:04
@jhssilva
jhssilva requested a review from a team as a code owner August 14, 2026 08:04
@jhssilva
jhssilva requested review from buranmert and nchapma2 and removed request for a team August 14, 2026 08:04
@buranmert
buranmert requested a balanced review from Copilot August 14, 2026 08:28
@buranmert

Copy link
Copy Markdown

relevant comment from the previous PR: #470 (comment)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Friend, this PR synchronizes esbuild artifact rewriting with Error Tracking sourcemap uploads.

Changes:

  • Adds an artifact-readiness barrier to shared context.
  • Delays and deduplicates sourcemap uploads until injection finishes.
  • Adds barrier and debug-ID regression coverage.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/core/src/types.ts Defines artifact barrier APIs.
packages/factory/src/helpers/context.ts Implements barrier lifecycle.
packages/factory/src/helpers/context.test.ts Tests resolution, rejection, and reuse.
packages/plugins/injection/src/index.ts Marks esbuild artifacts pending.
packages/plugins/injection/src/esbuild.ts Resolves the barrier after rewriting.
packages/plugins/error-tracking/src/index.ts Gates and deduplicates uploads.
packages/plugins/error-tracking/src/index.test.ts Adds synchronization and debug-ID tests.
packages/tests/src/_jest/helpers/mocks.ts Extends context mocks.
Suppressed comments (1)

packages/plugins/error-tracking/src/index.test.ts:111

  • Split the mapped promise and the push into named steps. The current nested calls violate the repository’s call-argument convention and make this assertion setup harder to follow.
            debugIdsAtUpload.push(
                ...(await Promise.all(
                    javascriptOutputs.map(({ filepath }) => extractDebugId(filepath)),
                )),
            );

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


const handleOrQueueSourcemaps = async () => {
if (context.artifactsPending) {
context.queue(handleSourcemaps());
);
const plugin = getPlugins(arg)[0];

const buildReportHook = plugin.buildReport!(getMockBuildReport());

@buranmert buranmert left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

that's a bit beyond my understanding of JS build plugins for me to propose a better way to achieve that.
i'm fine as long as our end-to-end tests pass 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants