Skip to content

Commit 23ef09b

Browse files
antoniskahest
andauthored
RN: Add unhandled promise rejection page (#14236)
<!-- Use this checklist to make sure your PR is ready for merge. You may delete any sections you don't need. --> ## DESCRIBE YOUR PR *Tell us what you're changing and why. If your PR **resolves an issue**, please link it so it closes automatically.* Adds unhandled promise rejection page to align with the new implementation in getsentry/sentry-react-native#4826 shipped in `6.15.0`. Fixes getsentry/sentry-react-native#4862 ## IS YOUR CHANGE URGENT? Help us prioritize incoming PRs by letting us know when the change needs to go live. - [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE --> - [ ] Other deadline: <!-- ENTER DATE HERE --> - [x] None: Not urgent, can wait up to 1 week+ ## SLA - Teamwork makes the dream work, so please add a reviewer to your PRs. - Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it. Thanks in advance for your help! ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) ## LEGAL BOILERPLATE <!-- Sentry employees and contractors can delete or ignore this section. --> Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms. ## EXTRA RESOURCES - [Sentry Docs contributor guide](https://docs.sentry.io/contributing/) --------- Co-authored-by: Karl Heinz Struggl <[email protected]>
1 parent 381c26e commit 23ef09b

File tree

2 files changed

+170
-61
lines changed

2 files changed

+170
-61
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Unhandled Promise Rejections
3+
description: "Learn about Sentry's Unhandled Promise Rejections handling in React Native."
4+
sidebar_order: 60
5+
---
6+
7+
Sentry automatically tracks unhandled promise rejections in React Native applications. Since version `6.15.0` the SDK uses engine-specific implementations to ensure reliable tracking across different JavaScript engines including Hermes, JavaScriptCore (JSC), and React Native Web environments.
8+
9+
## Configuration
10+
11+
Promise rejection tracking is enabled by default when you initialize Sentry. You can control promise rejection tracking through the `reactNativeErrorHandlersIntegration`:
12+
13+
```javascript
14+
import * as Sentry from '@sentry/react-native';
15+
16+
Sentry.init({
17+
dsn: "___PUBLIC_DSN___",
18+
integrations: [
19+
Sentry.reactNativeErrorHandlersIntegration({
20+
onunhandledrejection: false, // Disables promise rejection tracking
21+
}),
22+
],
23+
});
24+
```
25+
26+
## Engine-Specific Behavior
27+
28+
### Hermes Engine
29+
30+
When using Hermes, Sentry uses the engine's native promise rejection tracking capabilities.
31+
32+
<Alert>
33+
34+
Enabling Hermes rejection tracking will overwrite existing hooks due to limitations of the engine. Only one promise rejection tracker can be active at a time.
35+
36+
</Alert>
37+
38+
### JavaScriptCore (JSC)
39+
40+
For JSC environments, Sentry uses Promise polyfill with rejection tracking capabilities. This approach also overwrites existing hooks.
41+
42+
<Alert>
43+
44+
The Promise polyfill is used to ensure compatibility and provide rejection tracking functionality that may not be available natively in older JSC versions.
45+
46+
</Alert>
47+
48+
### React Native Web
49+
50+
For React Native Web, Sentry leverages the browser's native promise rejection tracking capabilities, providing seamless integration with web debugging tools.
51+
52+
## Multiple Tools and Logging
53+
54+
When using multiple tools for promise rejection tracking, be aware that:
55+
56+
- **Hermes**: Only one rejection tracker can be active. Sentry will take precedence.
57+
- **JSC**: Sentry's Promise polyfill will override existing handlers.
58+
- **React Native Web**: Can coexist better with other browser-based debugging tools.
59+
60+
### Example: Using Sentry with Other Debugging Tools
61+
62+
```javascript
63+
import * as Sentry from '@sentry/react-native';
64+
65+
// For development, you might want to disable Sentry's tracking
66+
// to allow other debugging tools to handle promise rejections
67+
if (__DEV__) {
68+
Sentry.init({
69+
dsn: "___PUBLIC_DSN___",
70+
integrations: [
71+
Sentry.reactNativeErrorHandlersIntegration({
72+
onunhandledrejection: false, // Let other tools handle in development
73+
}),
74+
],
75+
});
76+
} else {
77+
// In production, use Sentry's tracking
78+
Sentry.init({
79+
dsn: "___PUBLIC_DSN___",
80+
// Default configuration with promise tracking enabled
81+
});
82+
}
83+
```
84+
85+
## Troubleshooting
86+
87+
Due to an issue with React Native's dependencies, unhandled promise rejections might not be correctly caught by Sentry when using the JavaScriptCore (JSC) engine or a React Native SDK version before `6.15.0`.
88+
89+
If the promise rejection handler was not correctly attached, our SDK might issue a warning:
90+
91+
> WARN: Unhandled promise rejections might not be caught by Sentry. Read about how to fix this on our troubleshooting docs.
92+
93+
Otherwise, we will let you know that the handler is attached:
94+
95+
> [Sentry] Unhandled promise rejections will be caught by Sentry.
96+
97+
### Auto Patching (Default Behavior)
98+
99+
By default we will patch the global `Promise` instance to ensure it matches exactly with the version that React Native uses.
100+
101+
#### Using With Other Polyfills
102+
103+
If you use a polyfilling library that patches the global `Promise` instance, you'll need to make sure you run the polyfill **after** `Sentry.init` is called.
104+
105+
106+
```javascript
107+
import allSettled from "promise.allsettled";
108+
109+
Sentry.init({
110+
dsn: "___PUBLIC_DSN___",
111+
});
112+
// Any Promise polyfilling must occur AFTER Sentry.init
113+
// This step globally patches Promise.
114+
allSettled.shim();
115+
116+
// Separate core-js example
117+
import "core-js/stable/promise/all-settled";
118+
```
119+
120+
Your linter might throw some errors here, but this step is necessary.
121+
122+
#### Disable Auto Patching
123+
124+
You can disable the global promise patching by passing `patchGlobalPromise: false` in either `Sentry.init` or the `ReactNativeErrorHandlers` integration. Note that if you disable our auto patching, to ensure that unhandled rejections are still caught, you will need to [manually force a package resolution](#manually-forcing-a-package-resolution).
125+
126+
### Manually Forcing a Package Resolution
127+
128+
You don't need to perform the steps below if you don't disable [auto patching](#auto-patching-default-behavior). You'll need to ensure that the version of `promise` that you use matches exactly with the version that React Native uses.
129+
130+
1. Check the version of `promise` that your version of `react-native` uses. You can do this by going into `node_modules/react-native/package.json` and checking the version there, for example we find that it uses `^8.0.3`:
131+
132+
```json {filename:node_modules/react-native/package.json}
133+
{
134+
"dependencies": {
135+
// ...
136+
"promise": "^8.0.3"
137+
}
138+
}
139+
```
140+
141+
2. Add a package resolution with the same version as `react-native`'s' to **your** `package.json` file, this will force this version to be used. You will then need to run a fresh `yarn install` or `npm install` to use the package resolution you just added.
142+
143+
```json {filename:package.json}
144+
{
145+
"resolutions": {
146+
"promise": "^8.0.3"
147+
}
148+
}
149+
```
150+
151+
<Alert>
152+
153+
Package resolutions are currently only supporred by `yarn`. If you use `npm`, you can use a third-party package called [npm-force-resolutions](https://www.npmjs.com/package/npm-force-resolutions) to achieve this.
154+
155+
</Alert>
156+
157+
3. If the fix is successful, our SDK will no longer display the above warning and will indicate that promise rejections will be caught.
158+
159+
160+
## Migration from Older Versions
161+
162+
If you're upgrading from an older version of Sentry React Native:
163+
164+
1. Remove any manual Promise polyfill resolutions from your `package.json`
165+
2. Remove any custom promise rejection handling code
166+
3. Update to the latest version of `@sentry/react-native`
167+
4. Test that promise rejections are being captured correctly
168+
169+
The new engine-specific approach should resolve previous compatibility issues automatically.

docs/platforms/react-native/troubleshooting/index.mdx

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -33,67 +33,7 @@ Otherwise, we will let you know that the handler is attached:
3333

3434
> [Sentry] Unhandled promise rejections will be caught by Sentry.
3535
36-
### Auto Patching (Default Behavior)
37-
38-
By default we will patch the global `Promise` instance to ensure it matches exactly with the version that React Native uses.
39-
40-
#### Using With Other Polyfills
41-
42-
If you use a polyfilling library that patches the global `Promise` instance, you'll need to make sure you run the polyfill **after** `Sentry.init` is called.
43-
44-
45-
```javascript
46-
import allSettled from "promise.allsettled";
47-
48-
Sentry.init({
49-
dsn: "___PUBLIC_DSN___",
50-
});
51-
// Any Promise polyfilling must occur AFTER Sentry.init
52-
// This step globally patches Promise.
53-
allSettled.shim();
54-
55-
// Separate core-js example
56-
import "core-js/stable/promise/all-settled";
57-
```
58-
59-
Your linter might throw some errors here, but this step is necessary.
60-
61-
#### Disable Auto Patching
62-
63-
You can disable the global promise patching by passing `patchGlobalPromise: false` in either `Sentry.init` or the `ReactNativeErrorHandlers` integration. Note that if you disable our auto patching, to ensure that unhandled rejections are still caught, you will need to [manually force a package resolution](#manually-forcing-a-package-resolution).
64-
65-
### Manually Forcing a Package Resolution
66-
67-
You don't need to perform the steps below if you don't disable [auto patching](#auto-patching-default-behavior). You'll need to ensure that the version of `promise` that you use matches exactly with the version that React Native uses.
68-
69-
1. Check the version of `promise` that your version of `react-native` uses. You can do this by going into `node_modules/react-native/package.json` and checking the version there, for example we find that it uses `^8.0.3`:
70-
71-
```json {filename:node_modules/react-native/package.json}
72-
{
73-
"dependencies": {
74-
// ...
75-
"promise": "^8.0.3"
76-
}
77-
}
78-
```
79-
80-
2. Add a package resolution with the same version as `react-native`'s' to **your** `package.json` file, this will force this version to be used. You will then need to run a fresh `yarn install` or `npm install` to use the package resolution you just added.
81-
82-
```json {filename:package.json}
83-
{
84-
"resolutions": {
85-
"promise": "^8.0.3"
86-
}
87-
}
88-
```
89-
90-
<Alert>
91-
92-
Package resolutions are currently only supporred by `yarn`. If you use `npm`, you can use a third-party package called [npm-force-resolutions](https://www.npmjs.com/package/npm-force-resolutions) to achieve this.
93-
94-
</Alert>
95-
96-
3. If the fix is successful, our SDK will no longer display the above warning and will indicate that promise rejections will be caught.
36+
You can read more about how to set up unhandled promise rejections in the [Unhandled Promise Rejections guide](/platforms/react-native/integrations/unhandled-rejections/).
9737

9838
## Source Maps
9939

0 commit comments

Comments
 (0)