Browse Source

feat(javascript-sdk): Fetch source files inside event-processor in order to determine debug IDs (#50938)

Luca Forstner 1 year ago
parent
commit
485e022932
3 changed files with 49 additions and 11 deletions
  1. 2 1
      fixtures/js-stubs/config.js
  2. 45 9
      static/app/bootstrap/initializeSdk.tsx
  3. 2 1
      static/app/types/system.tsx

+ 2 - 1
fixtures/js-stubs/config.js

@@ -39,7 +39,8 @@ export function Config(params = {}) {
     sentryConfig: {
       dsn: 'test-dsn',
       release: '1.0.0.-dev',
-      whitelistUrls: [],
+      allowUrls: [],
+      tracePropagationTargets: [],
     },
     distPrefix: '',
     apmSampling: 1,

+ 45 - 9
static/app/bootstrap/initializeSdk.tsx

@@ -11,6 +11,7 @@ import {Config} from 'sentry/types';
 import {addExtraMeasurements, addUIElementTag} from 'sentry/utils/performanceForSentry';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 import {HTTPTimingIntegration} from 'sentry/utils/performanceForSentry/integrations';
+import {getErrorDebugIds} from 'sentry/utils/getErrorDebugIds';
 
 const SPA_MODE_ALLOW_URLS = [
   'localhost',
@@ -19,6 +20,12 @@ const SPA_MODE_ALLOW_URLS = [
   'webpack-internal://',
 ];
 
+const SPA_MODE_TRACE_PROPAGATION_TARGETS = [
+  'localhost',
+  'dev.getsentry.net',
+  'sentry.dev',
+];
+
 // We don't care about recording breadcrumbs for these hosts. These typically
 // pollute our breadcrumbs since they may occur a LOT.
 //
@@ -39,12 +46,9 @@ const shouldEnableBrowserProfiling = window?.__initialData?.user?.isSuperuser;
  * (e.g.  `static/views/integrationPipeline`)
  */
 function getSentryIntegrations(sentryConfig: Config['sentryConfig'], routes?: Function) {
-  const extraTracingOrigins = SPA_DSN
-    ? SPA_MODE_ALLOW_URLS
-    : [...sentryConfig?.whitelistUrls];
-  const partialTracingOptions: Partial<BrowserTracing['options']> = {
-    tracingOrigins: ['localhost', /^\//, ...extraTracingOrigins],
-  };
+  const extraTracePropagationTargets = SPA_DSN
+    ? SPA_MODE_TRACE_PROPAGATION_TARGETS
+    : [...sentryConfig?.tracePropagationTargets];
 
   const integrations = [
     new ExtraErrorData({
@@ -65,7 +69,7 @@ function getSentryIntegrations(sentryConfig: Config['sentryConfig'], routes?: Fu
         enableInteractions: true,
         onStartRouteTransaction: Sentry.onProfilingStartRouteTransaction,
       },
-      ...partialTracingOptions,
+      tracePropagationTargets: ['localhost', /^\//, ...extraTracePropagationTargets],
     }),
     new Sentry.BrowserProfilingIntegration(),
     new HTTPTimingIntegration(),
@@ -88,7 +92,7 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
     ...sentryConfig,
     /**
      * For SPA mode, we need a way to overwrite the default DSN from backend
-     * as well as `whitelistUrls`
+     * as well as `allowUrls`
      */
     dsn: SPA_DSN || sentryConfig?.dsn,
     /**
@@ -97,7 +101,7 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
      * from backend.
      */
     release: SENTRY_RELEASE_VERSION ?? sentryConfig?.release,
-    allowUrls: SPA_DSN ? SPA_MODE_ALLOW_URLS : sentryConfig?.whitelistUrls,
+    allowUrls: SPA_DSN ? SPA_MODE_ALLOW_URLS : sentryConfig?.allowUrls,
     integrations: getSentryIntegrations(sentryConfig, routes),
     tracesSampleRate,
     // @ts-expect-error not part of browser SDK types yet
@@ -173,6 +177,38 @@ export function initializeSdk(config: Config, {routes}: {routes?: Function} = {}
     },
   });
 
+  // Event processor to fill the debug_meta field with debug IDs based on the
+  // files the error touched. (files inside the stacktrace)
+  const debugIdPolyfillEventProcessor = async (event: Event, hint: Sentry.EventHint) => {
+    if (!(hint.originalException instanceof Error)) {
+      return event;
+    }
+
+    try {
+      const debugIdMap = await getErrorDebugIds(hint.originalException);
+
+      // Fill debug_meta information
+      event.debug_meta = {};
+      event.debug_meta.images = [];
+      const images = event.debug_meta.images;
+      Object.keys(debugIdMap).forEach(filename => {
+        images.push({
+          type: 'sourcemap',
+          code_file: filename,
+          debug_id: debugIdMap[filename],
+        });
+      });
+    } catch (e) {
+      event.extra = event.extra || {};
+      event.extra.debug_id_fetch_error = String(e);
+    }
+
+    return event;
+  };
+  debugIdPolyfillEventProcessor.id = 'debugIdPolyfillEventProcessor';
+
+  Sentry.addGlobalEventProcessor(debugIdPolyfillEventProcessor);
+
   // Track timeOrigin Selection by the SDK to see if it improves transaction durations
   Sentry.addGlobalEventProcessor((event: Sentry.Event, _hint?: Sentry.EventHint) => {
     event.tags = event.tags || {};

+ 2 - 1
static/app/types/system.tsx

@@ -152,9 +152,10 @@ export interface Config {
   privacyUrl: string | null;
 
   sentryConfig: {
+    allowUrls: string[];
     dsn: string;
     release: string;
-    whitelistUrls: string[];
+    tracePropagationTargets: string[];
     profilesSampleRate?: number;
   };
   singleOrganization: boolean;