Browse Source

feat(u2f): Register fallback promises (#73400)

Scott Cooper 4 days ago
parent
commit
e5e2877185
2 changed files with 40 additions and 5 deletions
  1. 22 0
      static/app/utils/getPreloadedData.spec.tsx
  2. 18 5
      static/app/utils/getPreloadedData.ts

+ 22 - 0
static/app/utils/getPreloadedData.spec.tsx

@@ -0,0 +1,22 @@
+import {getPreloadedDataPromise} from './getPreloadedData';
+
+describe('getPreloadedDataPromise', () => {
+  beforeEach(() => {
+    (window as any).__sentry_preload = {
+      orgSlug: 'slug',
+    };
+  });
+  it('should register fallback promise', async () => {
+    const fallback = jest.fn(() => Promise.resolve('fallback'));
+    const result = await getPreloadedDataPromise('name', 'slug', fallback);
+    expect(result).toBe('fallback');
+    expect((window as any).__sentry_preload.name_fallback).toBeInstanceOf(Promise);
+  });
+  it('should only call fallback on failure', async () => {
+    (window as any).__sentry_preload.name = Promise.resolve('success');
+    const fallback = jest.fn();
+    const result = await getPreloadedDataPromise('name', 'slug', fallback, true);
+    expect(result).toBe('success');
+    expect(fallback).not.toHaveBeenCalled();
+  });
+});

+ 18 - 5
static/app/utils/getPreloadedData.ts

@@ -4,8 +4,21 @@ export async function getPreloadedDataPromise(
   fallback: () => Promise<any>,
   usePreload?: boolean
 ) {
+  const data = (window as any).__sentry_preload;
+  /**
+   * Save the fallback promise to `__sentry_preload` to allow the sudo modal to wait
+   * for the promise to resolve
+   */
+  const wrappedFallback = () => {
+    const fallbackAttribute = `${name}_fallback`;
+    const promise = fallback();
+    if (data) {
+      data[fallbackAttribute] = promise;
+    }
+    return promise;
+  };
+
   try {
-    const data = (window as any).__sentry_preload;
     if (
       !usePreload ||
       !data ||
@@ -14,15 +27,15 @@ export async function getPreloadedDataPromise(
       !data[name] ||
       !data[name].then
     ) {
-      return await fallback();
+      return await wrappedFallback();
     }
-    const result = await data[name].catch(fallback);
+    const result = await data[name].catch(() => null);
     if (!result) {
-      return await fallback();
+      return await wrappedFallback();
     }
     return await result;
   } catch (_) {
     //
   }
-  return await fallback();
+  return await wrappedFallback();
 }