getsentry / sentry-react-native

Official Sentry SDK for React-Native
https://sentry.io
MIT License
1.55k stars 325 forks source link

TypeError: core.convertIntegrationFnToClass is not a function #3929

Open ollie-nye opened 3 days ago

ollie-nye commented 3 days ago

OS:

Platform:

SDK:

SDK version: @sentry/core@7.117.0 via @sentry/react-native@5.24.1 @sentry/core@8.11.0 via other internal dependencies

react-native version: 0.73.5

Are you using Expo?

Are you using sentry.io or on-premise?

If you are using sentry.io, please post a link to your issue so we can take a look:

Local test only, hasn't made it out to the build yet

Configuration:

(@sentry/react-native)

Sentry.init({
  dsn: config.SENTRY_DSN,
  enabled: !__DEV__,
  initialScope: {
    tags: {
      nativeVersion: Application.nativeApplicationVersion,
    },
  },
  ignoreErrors: [
    ...
  ],
  integrations: [
    new Sentry.ReactNativeTracing({
      routingInstrumentation,
      enableNativeFramesTracking: true,
      enableStallTracking: true,
    }),
  ],
});

I have the following issue:

TypeError: core.convertIntegrationFnToClass is not a function when using Jest to test an exception being reported correctly.

Steps to reproduce:

Test looks something like this:

import * as Sentry from '@sentry/react-native';
it('does the thing', () => {
  expect(Sentry.captureException).not.toHaveBeenCalled();
});

Jest has been set up to ignore transforms for @sentry/react-native, though I've also tried with @sentry/.* with the same outcome

Actual result:

Test suite failed to run

    TypeError: core.convertIntegrationFnToClass is not a function

    > 1 | import * as Sentry from '@sentry/react-native';
        | ^
      2 | it('does the thing', () => {
      3 |   expect(Sentry.captureException).not.toHaveBeenCalled();
      4 | });

      at Object.convertIntegrationFnToClass (../node_modules/src/integrations/breadcrumbs.ts:106:28)
      at Object.<anonymous> (../node_modules/@sentry/browser/cjs/sdk.js:8:21)
      at Object.<anonymous> (../node_modules/@sentry/browser/cjs/index.js:11:13)
      at Object.<anonymous> (../node_modules/@sentry/react-native/src/js/tracing/reactnativetracing.ts:3:1)
      at Object.<anonymous> (../node_modules/@sentry/react-native/src/js/tracing/addTracingExtensions.ts:6:1)
      at Object.<anonymous> (../node_modules/@sentry/react-native/src/js/index.ts:51:1)
      at Object.<anonymous> (src/Test.test.ts:1:1)

Expected result:

A passing test


We're currently migrating from sentry-expo and this behaved under that library but this is the last bit that's stumped us until we can move to @sentry/react-native. Thanks for any help or pointers anyone has!

krystofwoldrich commented 2 days ago

Hi @ollie-nye , thank you for the message, the RN SDK is not compatible with the JS v8 yet, we are working on the new major version as we speak https://github.com/getsentry/sentry-react-native/tree/v6.

If I understand it correct the following core results in the same error?

import * as Sentry from '@sentry/core';
it('does the thing', () => {
  expect(Sentry.captureException).not.toHaveBeenCalled();
});

I would recommend keeping the Sentry JS dependencies on @sentry/core@7.117.0 to avoid issues. From the stack trace it seem like ../node_modules/@sentry/browser is v7 which is correct, but then it load @sentry/core@8 instead of it specified v7 dependency. But I don't see why.

ollie-nye commented 2 days ago

Thanks for picking this up so quick! Importing core directly (with a bit of required mocking) seems to behave as it should do, interestingly:

import * as Sentry from '@sentry/core';

jest.mock('@sentry/core', () => {
  const actual = jest.requireActual('@sentry/core');
  return {
    ...actual,
    captureException: jest.fn(),
  };
});

it('does the thing', () => {
  expect(Sentry.captureException).not.toHaveBeenCalled();
});

Result:

 PASS  src/Test.test.tsx
  ✓ does the thing (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.625 s, estimated 1 s

We do have both v7 and v8 core in node_modules, because another dependency is pure javascript so has updated to v8 already. We only have v7 as a direct dependency though, with @sentry/react-native at 5.24.1

krystofwoldrich commented 1 day ago

@ollie-nye Thanks, that sounds correct.

As when directly importing the @sentry/core there is no clash. But when importing @sentry/react-native it's ready for v7 JS and it gets v8 which is not compatible.

It seem like that during the tests the wrong version of the @sentry/core package is loaded.

What version is ../node_modules/@sentry/browser?