Skip to content

Commit

Permalink
Use new JS SDK global object
Browse files Browse the repository at this point in the history
  • Loading branch information
krystofwoldrich committed Oct 21, 2022
1 parent 1ed0472 commit 98208ed
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 38 deletions.
7 changes: 3 additions & 4 deletions src/js/integrations/reactnativeerrorhandlers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { getCurrentHub } from '@sentry/core';
import { Integration, SeverityLevel } from '@sentry/types';
import { addExceptionMechanism, getGlobalObject, logger } from '@sentry/utils';
import { addExceptionMechanism, logger } from '@sentry/utils';

import { ReactNativeClient } from '../client';
import { RN_GLOBAL_OBJ } from '../utils/worldwide';

/** ReactNativeErrorHandlers Options */
interface ReactNativeErrorHandlersOptions {
Expand Down Expand Up @@ -142,9 +143,7 @@ export class ReactNativeErrorHandlers implements Integration {
// eslint-disable-next-line @typescript-eslint/no-var-requires,import/no-extraneous-dependencies
const Promise = require('promise/setimmediate/es6-extensions');

const _global = getGlobalObject<{ Promise: typeof Promise }>();

if (Promise !== _global.Promise) {
if (Promise !== RN_GLOBAL_OBJ.Promise) {
logger.warn(
'Unhandled promise rejections will not be caught by Sentry. Read about how to fix this on our troubleshooting page.'
);
Expand Down
6 changes: 3 additions & 3 deletions src/js/sdk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
getCurrentHub,
} from '@sentry/react';
import { Integration, Scope, StackFrame, UserFeedback } from '@sentry/types';
import { getGlobalObject, logger, stackParserFromStackParserOptions } from '@sentry/utils';
import { logger, stackParserFromStackParserOptions } from '@sentry/utils';
import * as React from 'react';

import { ReactNativeClient } from './client';
Expand All @@ -25,6 +25,7 @@ import { ReactNativeProfiler, ReactNativeTracing } from './tracing';
import { makeReactNativeTransport } from './transports/native';
import { makeUtf8TextEncoder } from './transports/TextEncoder';
import { safeFactory, safeTracesSampler } from './utils/safe';
import { RN_GLOBAL_OBJ } from './utils/worldwide';

const IGNORED_DEFAULT_INTEGRATIONS = [
'GlobalHandlers', // We will use the react-native internal handlers
Expand Down Expand Up @@ -130,8 +131,7 @@ export function init(passedOptions: ReactNativeOptions): void {
});
initAndBind(ReactNativeClient, options);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any
if (getGlobalObject<any>().HermesInternal) {
if (RN_GLOBAL_OBJ.HermesInternal) {
getCurrentHub().setTag('hermes', 'true');
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/js/tracing/reactnavigation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable max-lines */
import { Transaction as TransactionType, TransactionContext } from '@sentry/types';
import { getGlobalObject, logger } from '@sentry/utils';
import { logger } from '@sentry/utils';

import { RN_GLOBAL_OBJ } from '../utils/worldwide';
import {
InternalRoutingInstrumentation,
OnConfirmRoute,
Expand Down Expand Up @@ -105,14 +106,12 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
public registerNavigationContainer(navigationContainerRef: any): void {
const _global = getGlobalObject<{ __sentry_rn_v5_registered?: boolean }>();

/* We prevent duplicate routing instrumentation to be initialized on fast refreshes
Explanation: If the user triggers a fast refresh on the file that the instrumentation is
initialized in, it will initialize a new instance and will cause undefined behavior.
*/
if (!_global.__sentry_rn_v5_registered) {
if (!RN_GLOBAL_OBJ.__sentry_rn_v5_registered) {
if ('current' in navigationContainerRef) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
this._navigationContainer = navigationContainerRef.current;
Expand Down Expand Up @@ -143,7 +142,7 @@ export class ReactNavigationInstrumentation extends InternalRoutingInstrumentati
}
}

_global.__sentry_rn_v5_registered = true;
RN_GLOBAL_OBJ.__sentry_rn_v5_registered = true;
} else {
logger.warn(
'[ReactNavigationInstrumentation] Received invalid navigation container ref!'
Expand Down
9 changes: 4 additions & 5 deletions src/js/tracing/reactnavigationv4.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable max-lines */
import { Transaction, TransactionContext } from '@sentry/types';
import { getGlobalObject, logger } from '@sentry/utils';
import { logger } from '@sentry/utils';

import { RN_GLOBAL_OBJ } from '../utils/worldwide';
import {
InternalRoutingInstrumentation,
OnConfirmRoute,
Expand Down Expand Up @@ -124,14 +125,12 @@ class ReactNavigationV4Instrumentation extends InternalRoutingInstrumentation {
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
public registerAppContainer(appContainerRef: any): void {
const _global = getGlobalObject<{ __sentry_rn_v4_registered?: boolean }>();

/* We prevent duplicate routing instrumentation to be initialized on fast refreshes
Explanation: If the user triggers a fast refresh on the file that the instrumentation is
initialized in, it will initialize a new instance and will cause undefined behavior.
*/
if (!_global.__sentry_rn_v4_registered) {
if (!RN_GLOBAL_OBJ.__sentry_rn_v4_registered) {
if ('current' in appContainerRef) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
this._appContainer = appContainerRef.current;
Expand All @@ -153,7 +152,7 @@ class ReactNavigationV4Instrumentation extends InternalRoutingInstrumentation {
this._initialStateHandled = true;
}

_global.__sentry_rn_v4_registered = true;
RN_GLOBAL_OBJ.__sentry_rn_v4_registered = true;
} else {
logger.warn(
'[ReactNavigationV4Instrumentation] Received invalid app container ref!'
Expand Down
10 changes: 10 additions & 0 deletions src/js/utils/worldwide.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GLOBAL_OBJ, InternalGlobal } from '@sentry/utils';

export interface ReactNativeInternalGlobal extends InternalGlobal {
__sentry_rn_v4_registered?: boolean;
__sentry_rn_v5_registered?: boolean;
HermesInternal: unknown;
Promise: unknown;
}

export const RN_GLOBAL_OBJ = GLOBAL_OBJ as ReactNativeInternalGlobal;
18 changes: 7 additions & 11 deletions test/tracing/reactnavigation.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Transaction } from '@sentry/tracing';
import { TransactionContext } from '@sentry/types';
import { getGlobalObject } from '@sentry/utils';

import {
BLANK_TRANSACTION_CONTEXT,
NavigationRoute,
ReactNavigationInstrumentation,
} from '../../src/js/tracing/reactnavigation';
import { RN_GLOBAL_OBJ } from '../../src/js/utils/worldwide';

const dummyRoute = {
name: 'Route',
Expand Down Expand Up @@ -36,12 +36,8 @@ const getMockTransaction = () => {
return transaction;
};

const _global = getGlobalObject<{
__sentry_rn_v5_registered?: boolean;
}>();

afterEach(() => {
_global.__sentry_rn_v5_registered = false;
RN_GLOBAL_OBJ.__sentry_rn_v5_registered = false;

jest.resetAllMocks();
});
Expand Down Expand Up @@ -120,7 +116,7 @@ describe('ReactNavigationInstrumentation', () => {
someParam: 42,
},
};
// If .getCurrentRoute() is undefined, ignore state change
// If .getCurrentRoute() is undefined, ignore state change
mockNavigationContainerRef.current.currentRoute = undefined;
mockNavigationContainerRef.current.listeners['state']({});

Expand Down Expand Up @@ -297,7 +293,7 @@ describe('ReactNavigationInstrumentation', () => {
current: mockNavigationContainer,
});

expect(_global.__sentry_rn_v5_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v5_registered).toBe(true);

// eslint-disable-next-line @typescript-eslint/unbound-method
expect(mockNavigationContainer.addListener).toHaveBeenNthCalledWith(
Expand All @@ -318,7 +314,7 @@ describe('ReactNavigationInstrumentation', () => {
const mockNavigationContainer = new MockNavigationContainer();
instrumentation.registerNavigationContainer(mockNavigationContainer);

expect(_global.__sentry_rn_v5_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v5_registered).toBe(true);

// eslint-disable-next-line @typescript-eslint/unbound-method
expect(mockNavigationContainer.addListener).toHaveBeenNthCalledWith(
Expand All @@ -335,15 +331,15 @@ describe('ReactNavigationInstrumentation', () => {
});

test('does not register navigation container if there is an existing one', () => {
_global.__sentry_rn_v5_registered = true;
RN_GLOBAL_OBJ.__sentry_rn_v5_registered = true;

const instrumentation = new ReactNavigationInstrumentation();
const mockNavigationContainer = new MockNavigationContainer();
instrumentation.registerNavigationContainer({
current: mockNavigationContainer,
});

expect(_global.__sentry_rn_v5_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v5_registered).toBe(true);

// eslint-disable-next-line @typescript-eslint/unbound-method
expect(mockNavigationContainer.addListener).not.toHaveBeenCalled();
Expand Down
16 changes: 6 additions & 10 deletions test/tracing/reactnavigationv4.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Transaction } from '@sentry/tracing';
import { TransactionContext } from '@sentry/types';
import { getGlobalObject } from '@sentry/utils';

import {
AppContainerInstance,
Expand All @@ -10,6 +9,7 @@ import {
NavigationStateV4,
ReactNavigationV4Instrumentation,
} from '../../src/js/tracing/reactnavigationv4';
import { RN_GLOBAL_OBJ } from '../../src/js/utils/worldwide';

const initialRoute = {
routeName: 'Initial Route',
Expand Down Expand Up @@ -82,12 +82,8 @@ class MockAppContainer implements AppContainerInstance {
}
}

const _global = getGlobalObject<{
__sentry_rn_v4_registered?: boolean;
}>();

afterEach(() => {
_global.__sentry_rn_v4_registered = false;
RN_GLOBAL_OBJ.__sentry_rn_v4_registered = false;

jest.resetAllMocks();
});
Expand Down Expand Up @@ -313,7 +309,7 @@ describe('ReactNavigationV4Instrumentation', () => {
current: mockAppContainer,
});

expect(_global.__sentry_rn_v4_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v4_registered).toBe(true);

// eslint-disable-next-line @typescript-eslint/unbound-method
expect(instrumentation.onRouteWillChange).toHaveBeenCalledTimes(1);
Expand All @@ -336,7 +332,7 @@ describe('ReactNavigationV4Instrumentation', () => {
const mockAppContainer = new MockAppContainer();
instrumentation.registerAppContainer(mockAppContainer);

expect(_global.__sentry_rn_v4_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v4_registered).toBe(true);

// eslint-disable-next-line @typescript-eslint/unbound-method
expect(instrumentation.onRouteWillChange).toHaveBeenCalledTimes(1);
Expand All @@ -345,7 +341,7 @@ describe('ReactNavigationV4Instrumentation', () => {
});

test('does not register navigation container if there is an existing one', async () => {
_global.__sentry_rn_v4_registered = true;
RN_GLOBAL_OBJ.__sentry_rn_v4_registered = true;

const instrumentation = new ReactNavigationV4Instrumentation();
const mockTransaction = getMockTransaction();
Expand All @@ -361,7 +357,7 @@ describe('ReactNavigationV4Instrumentation', () => {
const mockAppContainer = new MockAppContainer();
instrumentation.registerAppContainer(mockAppContainer);

expect(_global.__sentry_rn_v4_registered).toBe(true);
expect(RN_GLOBAL_OBJ.__sentry_rn_v4_registered).toBe(true);

await new Promise<void>((resolve) => {
setTimeout(() => {
Expand Down

0 comments on commit 98208ed

Please sign in to comment.