Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [RUM-8429] Report an error when lazy loading the recorder module fails #3326

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sethfowler-datadog
Copy link
Contributor

Motivation

Lazy loading the recorder module can fail, either due to a customer-side issue (like a CSP misconfiguration) or due to an issue on our end (like failing to upload the chunk to the CDN). We should report an error when this happens and add telemetry.

The current situation is a bummer since the failure is totally silent; no error is reported anywhere. I spent quite a bit of time over the past couple of days trying to understand why one of my local changes wasn't working. The root cause turned out to be #3324; the problem would've been instantly obvious with the changes in this PR.

Changes

This PR adapts the current error reporting we do when the compression worker fails to load so that it can be used for both the compression worker and the lazy loaded recorder module. We now use the same code in both places, so our existing infrastructure for detecting CSP-related errors can be reused.

Testing

  • Local
  • Staging
  • Unit
  • End to end

I have gone over the contributing documentation.

@sethfowler-datadog sethfowler-datadog requested a review from a team as a code owner February 5, 2025 15:27
@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.

Project coverage is 92.91%. Comparing base (00f765c) to head (3026474).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
packages/rum/src/boot/lazyLoadRecorder.ts 66.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3326      +/-   ##
==========================================
- Coverage   92.95%   92.91%   -0.05%     
==========================================
  Files         297      299       +2     
  Lines        7840     7851      +11     
  Branches     1785     1786       +1     
==========================================
+ Hits         7288     7295       +7     
- Misses        552      556       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

})
}

export async function lazyLoadRecorderFrom(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This helper is here for testing purposes, so that it's possible to replace the real dynamic import with a version that throws a specific error.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe something like this would be simpler to get:

export async function lazyLoadRecorder(importRecorderImpl = importRecorder) {
  try {
    return await importRecorderImpl()
  } catch {
   reportScriptLoadingError({
      error,
      source: 'Recorder',
      scriptType: 'module',
    })
  }
}

async function importRecorder() {
   const module = await import(/* webpackChunkName: "recorder" */ './startRecording')
   return module.startRecording
}

@@ -261,6 +274,43 @@ describe('makeRecorderApi', () => {
})
})

describe('while lazy loading the recorder module', () => {
it('should report an error but no telemetry if CSP blocks the module', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that the behaviors we're testing for here are the same ones we already have for the compression worker; the lazy loaded recorder module will now report errors in the same way.

Copy link
Member

@BenoitZugmeyer BenoitZugmeyer Feb 10, 2025

Choose a reason for hiding this comment

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

💬 suggestion: ‏ those two tests should be moved to scriptLoadingError.spec.ts or lazyLoadRecorder.spec.ts

configuredUrl?: string | undefined
error: unknown
source: string
scriptType: 'module' | 'Worker'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The casing inconsistency here is a bit funky. I wanted to avoid changing the capitalization of "Worker" in case it would affect our telemetry metrics, but "Module" doesn't really feel right, so I ended up with this compromise.

Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 I don't think capitalization would affect our telemetry metrics tbh. Same for the verb. I'm fine if we just use a same verb everyone.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool! In that case, I'll make things a bit more uniform.

Copy link

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 147.04 KiB 147.27 KiB 231 B +0.15%
Logs 51.33 KiB 51.33 KiB 0 B 0.00%
Rum Slim 105.77 KiB 105.77 KiB 0 B 0.00%
Worker 24.50 KiB 24.50 KiB 0 B 0.00%
🚀 CPU Performance
Action Name Base Average Cpu Time (ms) Local Average Cpu Time (ms) 𝚫
addglobalcontext 0.002 0.002 -0.000
addaction 0.043 0.038 -0.004
addtiming 0.001 0.001 0.000
adderror 0.047 0.052 0.004
startstopsessionreplayrecording 0.008 0.015 0.007
startview 0.463 0.434 -0.029
logmessage 0.020 0.021 0.002
🧠 Memory Performance
Action Name Base Consumption Memory (bytes) Local Consumption Memory (bytes) 𝚫 (bytes)
addglobalcontext 28.58 KiB 27.36 KiB -1252 B
addaction 56.59 KiB 56.35 KiB -251 B
addtiming 26.74 KiB 27.05 KiB 312 B
adderror 59.51 KiB 57.93 KiB -1621 B
startstopsessionreplayrecording 25.61 KiB 24.77 KiB -867 B
startview 418.19 KiB 423.52 KiB 5.33 KiB
logmessage 60.99 KiB 62.69 KiB 1.70 KiB

🔗 RealWorld

})
}

export async function lazyLoadRecorderFrom(
Copy link
Member

Choose a reason for hiding this comment

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

Maybe something like this would be simpler to get:

export async function lazyLoadRecorder(importRecorderImpl = importRecorder) {
  try {
    return await importRecorderImpl()
  } catch {
   reportScriptLoadingError({
      error,
      source: 'Recorder',
      scriptType: 'module',
    })
  }
}

async function importRecorder() {
   const module = await import(/* webpackChunkName: "recorder" */ './startRecording')
   return module.startRecording
}

@@ -261,6 +274,43 @@ describe('makeRecorderApi', () => {
})
})

describe('while lazy loading the recorder module', () => {
it('should report an error but no telemetry if CSP blocks the module', async () => {
Copy link
Member

@BenoitZugmeyer BenoitZugmeyer Feb 10, 2025

Choose a reason for hiding this comment

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

💬 suggestion: ‏ those two tests should be moved to scriptLoadingError.spec.ts or lazyLoadRecorder.spec.ts

`${baseMessage} See documentation at ${DOCS_ORIGIN}/integrations/content_security_policy_logs/#use-csp-with-real-user-monitoring-and-session-replay`
)
} else {
addTelemetryError(error)
Copy link
Member

Choose a reason for hiding this comment

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

💬 suggestion: ‏I don't think we should report the error as telemetry, as there is high chances that we won't be able to do anything about it. Ex: the recorder fails to load because of a user connectivity issue.

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.

6 participants