getsentry / sentry-react-native

Official Sentry SDK for React Native
https://sentry.io
MIT License
1.56k stars 330 forks source link

Use Hermes Promise implementation `Promise.allSettled is undefined` #3957

Open ignaciosantise opened 1 month ago

ignaciosantise commented 1 month ago

OS:

Platform:

SDK:

SDK version: 0.0.0

react-native version: 5.26.0

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:

Link

Configuration:

(@sentry/react-native)

Sentry.init({
  dsn: 'https://...@sentry.io/...'
});

I have the following issue:

Promise.allSettled is undefined when Sentry is enabled in the app

Steps to reproduce:

Actual result:

error "Promise.allSettled is not a function"

Expected result:

The function works as expected

Minimal Reproducible Example I created a new project with Expo and added Sentry using the Wizard. Check the readme to reproduce the issue https://github.com/ignaciosantise/sentry-issue

Screenshots

Sentry enabled

https://github.com/user-attachments/assets/29427948-19ed-4260-b5a4-68994c55161f

Sentry disabled

https://github.com/user-attachments/assets/af4502b6-0d8c-4558-b404-014ac1be6c49

krystofwoldrich commented 1 month ago

Hi @ignaciosantise, you appear to have multiple versions of the "promise" package installed. This may cause unexpected behavior like undefined Promise.allSettled. Please install the promise package manually using the exact version as the React Native package.

In your case that is:

npm i promise@8.3.0

Detailed information here: https://docs.sentry.io/platforms/react-native/troubleshooting/#disable-auto-patching

ignaciosantise commented 1 month ago

Hi @krystofwoldrich 👋 thanks for the info

Adding a resolution solves the issue 👌

The sample project i provided is a brand new project and it already has this issue, so maybe worth exploring why Sentry uses the wrong promise package? So users don't have to do some hacks to solve this.

Anyway, thanks for your help 🤝

ignaciosantise commented 1 month ago

Also an improvement for your docs here https://docs.sentry.io/platforms/react-native/troubleshooting/#manually-forcing-a-package-resolution

Package resolutions are currently only supporred by yarn. If you use npm, you can use a third-party package called npm-force-resolutions to achieve this.

You can do that by using overrides in NPM

{
  "overrides": {
    "promise": "^8.0.3"
  }
}
joarkosberg commented 1 month ago

Might be related(?). We also got this issue after updating yarn to v3, which was part of the latest react native upgrade. We had multiple versions of promise before, but only got this problem after updating yarn. Adding resolutions field to package.json fixed it for us.

krystofwoldrich commented 1 month ago

Thank you @ignaciosantise, we will add this to the docs.

krystofwoldrich commented 1 month ago

What can we do to improve the situation?

  1. When Hermes enabled use it's implementation directly. Tracking can be enabled by global.HermesInternal?.enablePromiseRejectionTracker?.().

https://github.com/facebook/react-native/blob/714b502b0c7a5f897432dbad388c02d3b75b4689/packages/react-native/Libraries/Core/polyfillPromise.js#L25

For RN Web use the Sentry Browser JS rejection tracking https://github.com/getsentry/sentry-javascript/blob/27876437b7cf33e2a78b455d36d5b8102f17b878/packages/utils/src/instrument/globalUnhandledRejection.ts#L24

When in JSC projects check the RN version and the allSettled to provide better error message, which guides users to adding the latest Promise package.

  1. Vendor the latest Promise package. Will increase bundle size.
  2. Add the latest Promise package as dependency. Might cause dep conflicts and goes against Sentry's SDKs no deps strategy.