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

Disable enableNative if Native SDK was not initialized #3099

Merged
merged 11 commits into from
Jun 13, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixes

- Disable `enableNative` if Native SDK is not available ([#3099](https://github.com/getsentry/sentry-react-native/pull/3099))
- Dynamically resolve `collectModulesScript` path to support monorepos ([#3092])(https://github.com/getsentry/sentry-react-native/pull/3092)
- Native wrapper methods don't throw disabled error after re-initializing [#3093](https://github.com/getsentry/sentry-react-native/pull/3093)

Expand Down
13 changes: 8 additions & 5 deletions src/js/sdk.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Scope } from '@sentry/core';
import { getIntegrationsToSetup, hasTracingEnabled , Hub, initAndBind, makeMain, setExtra } from '@sentry/core';
import { getIntegrationsToSetup, hasTracingEnabled, Hub, initAndBind, makeMain, setExtra } from '@sentry/core';
import { HttpClient } from '@sentry/integrations';
import {
defaultIntegrations as reactDefaultIntegrations,
Expand Down Expand Up @@ -32,13 +32,13 @@ import { ReactNativeProfiler, ReactNativeTracing } from './tracing';
import { DEFAULT_BUFFER_SIZE, makeNativeTransportFactory } from './transports/native';
import { makeUtf8TextEncoder } from './transports/TextEncoder';
import { safeFactory, safeTracesSampler } from './utils/safe';
import { NATIVE } from './wrapper';

const IGNORED_DEFAULT_INTEGRATIONS = [
'GlobalHandlers', // We will use the react-native internal handlers
'TryCatch', // We don't need this
];
const DEFAULT_OPTIONS: ReactNativeOptions = {
enableNative: true,
enableNativeCrashHandling: true,
enableNativeNagger: true,
autoInitializeNativeSdk: true,
Expand All @@ -65,15 +65,18 @@ export function init(passedOptions: ReactNativeOptions): void {
// eslint-disable-next-line deprecation/deprecation
?? passedOptions.transportOptions?.bufferSize
?? DEFAULT_OPTIONS.maxQueueSize;

const enableNative = passedOptions.enableNative === undefined || passedOptions.enableNative
? NATIVE.isNativeAvailable()
: false;
const options: ReactNativeClientOptions = {
...DEFAULT_OPTIONS,
...passedOptions,
enableNative,
// If custom transport factory fails the SDK won't initialize
transport: passedOptions.transport
|| makeNativeTransportFactory({
enableNative: passedOptions.enableNative !== undefined
? passedOptions.enableNative
: DEFAULT_OPTIONS.enableNative
enableNative,
})
|| makeFetchTransport,
transportOptions: {
Expand Down
45 changes: 45 additions & 0 deletions test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,51 @@ describe('Tests the SDK functionality', () => {
});

describe('transport initialization', () => {
describe('native SDK unavailable', () => {
it('fetchTransport set and enableNative set to false', () => {
(NATIVE.isNativeAvailable as jest.Mock).mockImplementation(() => false);
init({});
// eslint-disable-next-line @typescript-eslint/unbound-method
expect(NATIVE.isNativeAvailable).toBeCalled();
// @ts-ignore enableNative not publicly available here.
expect(usedOptions()?.enableNative).toEqual(false);
expect(usedOptions()?.transport).toEqual(makeFetchTransport);
});

it('fetchTransport set and passed enableNative ignored when true', () => {
(NATIVE.isNativeAvailable as jest.Mock).mockImplementation(() => false);
init({ enableNative: true });
// eslint-disable-next-line @typescript-eslint/unbound-method
expect(NATIVE.isNativeAvailable).toBeCalled();
// @ts-ignore enableNative not publicly available here.
expect(usedOptions()?.enableNative).toEqual(false);
expect(usedOptions()?.transport).toEqual(makeFetchTransport);
});

it('fetchTransport set and isNativeAvailable not called when passed enableNative set to false', () => {
(NATIVE.isNativeAvailable as jest.Mock).mockImplementation(() => false);
init({ enableNative: false });
// eslint-disable-next-line @typescript-eslint/unbound-method
expect(NATIVE.isNativeAvailable).not.toBeCalled();
// @ts-ignore enableNative not publicly available here.
expect(usedOptions()?.enableNative).toEqual(false);
expect(usedOptions()?.transport).toEqual(makeFetchTransport);
});

it('custom transport set and enableNative set to false', () => {
(NATIVE.isNativeAvailable as jest.Mock).mockImplementation(() => false);
const mockTransport = jest.fn();
init({
transport: mockTransport,
});
expect(usedOptions()?.transport).toEqual(mockTransport);
// eslint-disable-next-line @typescript-eslint/unbound-method
expect(NATIVE.isNativeAvailable).toBeCalled();
// @ts-ignore enableNative not publicly available here.
expect(usedOptions()?.enableNative).toEqual(false);
});
});

it('uses transport from the options', () => {
const mockTransport = jest.fn();
init({
Expand Down