Browse Source

fix(stacktrace): Fix missing Prism.js language recording (#61454)

It looks like the `onLoad` only gets fired when the language does exist
but fails to load. What we really want is to record any languages that
we don't have the correct mapping for.

I also changed this to an analytic event because that will be easier to
query than a Sentry issue.
Malachi Willey 1 year ago
parent
commit
1d4b89153b

+ 4 - 0
static/app/utils/analytics/stackTraceAnalyticsEvents.tsx

@@ -72,6 +72,9 @@ export type StackTraceEventParameters = {
     project_slug: string;
     platform?: string;
   };
+  'stack_trace.prism_missing_language': {
+    attempted_language: string;
+  };
   'stack_trace.threads.thread_selected': {
     has_stacktrace: boolean;
     num_in_app_frames: number;
@@ -114,4 +117,5 @@ export const stackTraceEventMap: Record<keyof StackTraceEventParameters, string>
     'Stack Trace: Sort Option - Recent Last - Clicked',
   'stack_trace.threads.thread_selected': 'Stack Trace: Thread Selected',
   'stack_trace.threads.thread_selector_opened': 'Stack Trace: Thread Selector Opened',
+  'stack_trace.prism_missing_language': 'Stack Trace: Prism.js Language Not Found',
 };

+ 21 - 16
static/app/utils/usePrismTokens.tsx

@@ -1,8 +1,10 @@
-import {useEffect, useMemo, useState} from 'react';
+import {useCallback, useEffect, useMemo, useState} from 'react';
 import * as Sentry from '@sentry/react';
 import Prism from 'prismjs';
 
+import {trackAnalytics} from 'sentry/utils/analytics';
 import {loadPrismLanguage, prismLanguageMap} from 'sentry/utils/prism';
+import useOrganization from 'sentry/utils/useOrganization';
 
 type PrismHighlightParams = {
   code: string;
@@ -22,21 +24,23 @@ type IntermediateToken = {
 };
 
 const useLoadPrismLanguage = (language: string, {onLoad}: {onLoad: () => void}) => {
+  const organization = useOrganization({allowNull: true});
+
   useEffect(() => {
     if (!language) {
       return;
     }
 
-    loadPrismLanguage(language, {
-      onLoad,
-      onError: () => {
-        Sentry.captureException(
-          new Error('Prism.js failed to load language for stack trace'),
-          {extra: {language}}
-        );
-      },
-    });
-  }, [language, onLoad]);
+    if (!prismLanguageMap[language.toLowerCase()]) {
+      trackAnalytics('stack_trace.prism_missing_language', {
+        organization,
+        attempted_language: language.toLowerCase(),
+      });
+      return;
+    }
+
+    loadPrismLanguage(language, {onLoad});
+  }, [language, onLoad, organization]);
 };
 
 const getPrismGrammar = (language: string) => {
@@ -138,11 +142,12 @@ export const usePrismTokens = ({
   const [grammar, setGrammar] = useState<Prism.Grammar | null>(() =>
     getPrismGrammar(language)
   );
-  useLoadPrismLanguage(language, {
-    onLoad: () => {
-      setGrammar(getPrismGrammar(language));
-    },
-  });
+
+  const onLoad = useCallback(() => {
+    setGrammar(getPrismGrammar(language));
+  }, [language]);
+  useLoadPrismLanguage(language, {onLoad});
+
   const lines = useMemo(() => {
     try {
       if (!grammar) {