Skip to content

Commit 7f1d209

Browse files
authored
Hotfix: promise rejection configuration (#2239)
* fix: 🐛 ensure reportUnhandledPromiseRejectionsAsHandled is impemented in all platforms * update CHANGELOG.md * test: 🩹 fix lineNumber assertion * test: ✅ add react native scenario for reportUnhandledPromiseRejectionsAsHandled * build: 🩹 update react-native fixture generate script * fix: ✏️ update typo in scenario name
1 parent 356951b commit 7f1d209

File tree

15 files changed

+88
-14
lines changed

15 files changed

+88
-14
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [8.1.2] - 2024-10-24
4+
5+
### Fixed
6+
7+
- Ensure `reportUnhandledPromiseRejectionsAsHandled` is correctly handled for all platforms [#2239](https://github.com/bugsnag/bugsnag-js/pull/2239)
8+
39
## [8.1.1] - 2024-10-23
410

511
### Fixed

packages/browser/test/index.test.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import BugsnagBrowserStatic, { Breadcrumb, Session } from '../src/notifier'
1+
import BugsnagBrowserStatic, { Breadcrumb, BrowserConfig, Session } from '../src/notifier'
22

33
const DONE = window.XMLHttpRequest.DONE
44

@@ -137,7 +137,8 @@ describe('browser notifier', () => {
137137

138138
it('accepts all config options', (done) => {
139139
const Bugsnag = getBugsnag()
140-
Bugsnag.start({
140+
141+
const completeConfig: Required<BrowserConfig> = {
141142
apiKey: API_KEY,
142143
appVersion: '1.2.3',
143144
appType: 'worker',
@@ -161,18 +162,23 @@ describe('browser notifier', () => {
161162
releaseStage: 'production',
162163
maxBreadcrumbs: 20,
163164
enabledBreadcrumbTypes: ['manual', 'log', 'request'],
165+
context: 'contextual',
166+
featureFlags: [],
167+
plugins: [],
164168
user: null,
165169
metadata: {
166170
debug: { foo: 'bar' }
167171
},
168-
logger: undefined,
172+
logger: { debug: jest.fn(), info: jest.fn(), warn: jest.fn(), error: jest.fn() },
169173
redactedKeys: ['foo', /bar/],
170174
collectUserIp: true,
171175
maxEvents: 10,
172176
generateAnonymousId: false,
173-
trackInlineScripts: true
174-
})
177+
trackInlineScripts: true,
178+
reportUnhandledPromiseRejectionsAsHandled: true
179+
}
175180

181+
Bugsnag.start(completeConfig)
176182
Bugsnag.notify(new Error('123'), (event) => {
177183
return false
178184
}, (err, event) => {

packages/electron/test/type.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ describe.skip('@bugsnag/electron types', () => {
3232
plugins: [],
3333
user: { id: '1234-abcd' },
3434
appType: 'good',
35-
codeBundleId: '1245'
35+
codeBundleId: '1245',
36+
reportUnhandledPromiseRejectionsAsHandled: true
3637
})
3738
})
3839
})

packages/react-native/src/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const stringWithLength = require('@bugsnag/core/lib/validators/string-with-lengt
33
const rnPackage = require('react-native/package.json')
44
const iserror = require('iserror')
55

6-
const ALLOWED_IN_JS = ['onError', 'onBreadcrumb', 'logger', 'metadata', 'user', 'context', 'codeBundleId', 'plugins', 'featureFlags']
6+
const ALLOWED_IN_JS = ['onError', 'onBreadcrumb', 'logger', 'metadata', 'user', 'context', 'codeBundleId', 'plugins', 'featureFlags', 'reportUnhandledPromiseRejectionsAsHandled']
77
const allowedErrorTypes = () => ({
88
unhandledExceptions: true,
99
unhandledRejections: true,

packages/react-native/test/index.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ describe('react native notifier', () => {
108108
expect(NativeModules.BugsnagReactNative.addFeatureFlags).toHaveBeenCalled()
109109
})
110110

111+
it('accepts the reportUnhandledPromiseRejectionsAsHandled config option', () => {
112+
const warnMock = jest.spyOn(console, 'warn').mockImplementation(() => {})
113+
114+
Bugsnag.start({ reportUnhandledPromiseRejectionsAsHandled: true })
115+
116+
expect(warnMock).not.toHaveBeenCalled()
117+
})
118+
111119
describe('isStarted()', () => {
112120
it('returns false when the notifier has not been initialized', () => {
113121
expect(Bugsnag.isStarted()).toBe(false)

packages/react-native/types/bugsnag.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ interface ReactNativeSchema extends Config {
55
}
66

77
// these properties are allowed to be configured in the JS layer
8-
type Configurable = 'onError' | 'onBreadcrumb' | 'logger' | 'metadata' | 'user' | 'context' | 'plugins' | 'codeBundleId' | 'featureFlags'
8+
type Configurable = 'onError' | 'onBreadcrumb' | 'logger' | 'metadata' | 'user' | 'context' | 'plugins' | 'codeBundleId' | 'featureFlags' | 'reportUnhandledPromiseRejectionsAsHandled'
99

1010
type ReactNativeConfig = Pick<ReactNativeSchema, Configurable>
1111

scripts/generate-react-native-fixture.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ if (!process.env.SKIP_GENERATE_FIXTURE) {
6161
}
6262

6363
// create the test fixture
64-
const RNInitArgs = ['@react-native-community/cli@latest', 'init', 'reactnative', '--directory', fixtureDir, '--version', reactNativeVersion, '--npm', '--skip-install']
64+
const RNInitArgs = ['@react-native-community/cli@latest', 'init', 'reactnative', '--directory', fixtureDir, '--version', reactNativeVersion, '--pm', 'npm', '--skip-install']
6565
execFileSync('npx', RNInitArgs, { stdio: 'inherit' })
6666

6767
replaceGeneratedFixtureFiles()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var Bugsnag = require('@bugsnag/node')
2+
Bugsnag.start({
3+
reportUnhandledPromiseRejectionsAsHandled: true,
4+
apiKey: process.env.BUGSNAG_API_KEY,
5+
endpoints: {
6+
notify: process.env.BUGSNAG_NOTIFY_ENDPOINT,
7+
sessions: process.env.BUGSNAG_SESSIONS_ENDPOINT
8+
}
9+
})
10+
11+
Promise.reject(new Error('not handled'))

test/node/features/unhandled_errors.feature

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ Scenario: reporting unhandled promise rejections
3737
And the "file" of stack frame 0 equals "scenarios/unhandled-promise-rejection.js"
3838
And the "lineNumber" of stack frame 0 equals 10
3939

40-
Scenario: reporting unhandled promise rejections
41-
And I run the service "unhandled" with the command "node scenarios/unhandled-promise-rejection"
40+
Scenario: reporting unhandled promise rejections as handled
41+
And I run the service "unhandled" with the command "node scenarios/unhandled-promise-rejection-as-handled"
4242
And I wait to receive an error
4343
Then the error is valid for the error reporting API version "4" for the "Bugsnag Node" notifier
44-
And the event "unhandled" is true
44+
And the event "unhandled" is false
4545
And the event "severity" equals "error"
4646
And the event "severityReason.type" equals "unhandledPromiseRejection"
4747
And the exception "errorClass" equals "Error"
4848
And the exception "message" equals "not handled"
4949
And the exception "type" equals "nodejs"
50-
And the "file" of stack frame 0 equals "scenarios/unhandled-promise-rejection.js"
51-
And the "lineNumber" of stack frame 0 equals 10
50+
And the "file" of stack frame 0 equals "scenarios/unhandled-promise-rejection-as-handled.js"
51+
And the "lineNumber" of stack frame 0 equals 11
5252

5353
Scenario: not reporting unhandledRejections when autoDetectErrors is off
5454
And I run the service "unhandled" with the command "node scenarios/unhandled-promise-rejection-auto-notify-off"

test/react-native/features/fixtures/app/scenario_js/app/Scenarios.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export { UnhandledNativeErrorScenario } from './scenarios/UnhandledNativeErrorSc
77
export { UnhandledJsErrorScenario } from './scenarios/UnhandledJsErrorScenario'
88
export { UnhandledJsErrorSeverityScenario } from './scenarios/UnhandledJsErrorSeverityScenario'
99
export { UnhandledJsPromiseRejectionScenario } from './scenarios/UnhandledJsPromiseRejectionScenario'
10+
export { UnhandledJsPromiseRejectionAsHandledScenario } from './scenarios/UnhandledJsPromiseRejectionAsHandledScenario'
1011
export { RCTFatalScenario } from './scenarios/RCTFatalScenario'
1112

1213
// api-key-ios.feature

0 commit comments

Comments
 (0)