Skip to content

Commit fbb5084

Browse files
authored
fix(js): improved, unambiguous error message (#1428)
1 parent b5bd7e2 commit fbb5084

File tree

6 files changed

+29
-29
lines changed

6 files changed

+29
-29
lines changed

.github/workflows/node.js.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ jobs:
9999
npm run test:integration
100100
101101
- name: Upload Playwright Report
102-
uses: actions/upload-artifact@v3
102+
uses: actions/upload-artifact@v4
103103
if: failure()
104104
with:
105105
name: playwright-report

packages/js/src/server/integrations/uncaught_exception_monitor.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default class UncaughtExceptionMonitor {
1010

1111
constructor() {
1212
this.__isReporting = false
13-
this.__handlerAlreadyCalled = false
13+
this.__handlerAlreadyCalled = false
1414
this.__listener = this.makeListener()
1515
this.removeAwsLambdaListener()
1616
}
@@ -22,23 +22,23 @@ export default class UncaughtExceptionMonitor {
2222
makeListener() {
2323
const honeybadgerUncaughtExceptionListener = (uncaughtError: Error) => {
2424
if (this.__isReporting || !this.__client) { return }
25-
25+
2626
// report only the first error - prevent reporting recursive errors
2727
if (this.__handlerAlreadyCalled) {
2828
if (!this.hasOtherUncaughtExceptionListeners()) {
29-
fatallyLogAndExit(uncaughtError)
29+
fatallyLogAndExit(uncaughtError, 'uncaught exception')
3030
}
3131
return
3232
}
33-
33+
3434
this.__isReporting = true
3535
this.__client.notify(uncaughtError, {
3636
afterNotify: (_err, _notice) => {
3737
this.__isReporting = false
3838
this.__handlerAlreadyCalled = true
3939
this.__client.config.afterUncaught(uncaughtError)
4040
if (!this.hasOtherUncaughtExceptionListeners()) {
41-
fatallyLogAndExit(uncaughtError)
41+
fatallyLogAndExit(uncaughtError, 'uncaught exception')
4242
}
4343
}
4444
})
@@ -71,16 +71,16 @@ export default class UncaughtExceptionMonitor {
7171
* we want to report the exception to Honeybadger and
7272
* mimic the default behavior of NodeJs,
7373
* which is to exit the process with code 1
74-
*
74+
*
7575
* Node sets up domainUncaughtExceptionClear when we use domains.
7676
* Since they're not set up by a user, they shouldn't affect whether we exit or not
7777
*/
7878
hasOtherUncaughtExceptionListeners(): boolean {
7979
const allListeners = process.listeners('uncaughtException')
8080
const otherListeners = allListeners.filter(listener => (
81-
listener.name !== 'domainUncaughtExceptionClear'
81+
listener.name !== 'domainUncaughtExceptionClear'
8282
&& listener !== this.__listener
8383
))
8484
return otherListeners.length > 0
8585
}
86-
}
86+
}

packages/js/src/server/integrations/unhandled_rejection_monitor.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default class UnhandledRejectionMonitor {
2323
afterNotify: () => {
2424
this.__isReporting = false;
2525
if (!this.hasOtherUnhandledRejectionListeners()) {
26-
fatallyLogAndExit(reason as Error)
26+
fatallyLogAndExit(reason as Error, 'unhandled rejection')
2727
}
2828
}
2929
})

packages/js/src/server/util.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import { promisify } from 'util'
66

77
const readFile = promisify(fs.readFile)
88

9-
export function fatallyLogAndExit(err: Error): never {
10-
console.error('[Honeybadger] Exiting process due to uncaught exception')
9+
export function fatallyLogAndExit(err: Error, source: string): never {
10+
console.error(`[Honeybadger] Exiting process due to ${source}`)
1111
console.error(err.stack || err)
1212
process.exit(1)
1313
}

packages/js/test/unit/server/integrations/uncaught_exception_monitor.server.test.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('UncaughtExceptionMonitor', () => {
1919
beforeEach(() => {
2020
// We just need a really basic client, so ignoring type issues here
2121
client = new TestClient(
22-
{ apiKey: 'testKey', afterUncaught: jest.fn(), logger: nullLogger() },
22+
{ apiKey: 'testKey', afterUncaught: jest.fn(), logger: nullLogger() },
2323
new TestTransport()
2424
) as unknown as typeof Singleton
2525
uncaughtExceptionMonitor = new UncaughtExceptionMonitor()
@@ -83,27 +83,27 @@ describe('UncaughtExceptionMonitor', () => {
8383
it('does nothing if our listener is not present', () => {
8484
process.on('uncaughtException', (err) => { console.log(err) })
8585
expect(getListenerCount()).toBe(1)
86-
86+
8787
uncaughtExceptionMonitor.maybeRemoveListener()
8888
expect(getListenerCount()).toBe(1)
8989
})
9090
})
9191

92-
describe('__listener', () => {
93-
const error = new Error('dang, broken again')
92+
describe('__listener', () => {
93+
const error = new Error('dang, broken again')
9494

9595
it('calls notify, afterUncaught, and fatallyLogAndExit', (done) => {
9696
uncaughtExceptionMonitor.__listener(error)
9797
expect(notifySpy).toHaveBeenCalledTimes(1)
9898
expect(notifySpy).toHaveBeenCalledWith(
99-
error,
99+
error,
100100
{ afterNotify: expect.any(Function) }
101101
)
102102
client.afterNotify(() => {
103103
expect(client.config.afterUncaught).toHaveBeenCalledWith(error)
104-
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(error)
104+
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(error, 'uncaught exception')
105105
done()
106-
})
106+
})
107107
})
108108

109109
it('returns if it is already reporting', () => {
@@ -132,15 +132,15 @@ describe('UncaughtExceptionMonitor', () => {
132132
uncaughtExceptionMonitor.__handlerAlreadyCalled = true
133133
uncaughtExceptionMonitor.__listener(error)
134134
expect(notifySpy).not.toHaveBeenCalled()
135-
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(error)
135+
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(error, 'uncaught exception')
136136
})
137137
})
138138

139139
describe('hasOtherUncaughtExceptionListeners', () => {
140140
it('returns true if there are user-added listeners', () => {
141141
uncaughtExceptionMonitor.maybeAddListener()
142142
process.on('uncaughtException', function domainUncaughtExceptionClear() {
143-
return
143+
return
144144
})
145145
process.on('uncaughtException', function userAddedListener() {
146146
return
@@ -151,7 +151,7 @@ describe('UncaughtExceptionMonitor', () => {
151151
it('returns false if there are only our expected listeners', () => {
152152
uncaughtExceptionMonitor.maybeAddListener()
153153
process.on('uncaughtException', function domainUncaughtExceptionClear() {
154-
return
154+
return
155155
})
156156
expect(uncaughtExceptionMonitor.hasOtherUncaughtExceptionListeners()).toBe(false)
157157
})

packages/js/test/unit/server/integrations/unhandled_rejection_monitor.server.test.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('UnhandledRejectionMonitor', () => {
1818
beforeEach(() => {
1919
// We just need a really basic client, so ignoring type issues here
2020
client = new TestClient(
21-
{ apiKey: 'testKey', afterUncaught: jest.fn(), logger: nullLogger() },
21+
{ apiKey: 'testKey', afterUncaught: jest.fn(), logger: nullLogger() },
2222
new TestTransport()
2323
) as unknown as typeof Singleton
2424
unhandledRejectionMonitor = new UnhandledRejectionMonitor()
@@ -69,28 +69,28 @@ describe('UnhandledRejectionMonitor', () => {
6969
it('does nothing if our listener is not present', () => {
7070
process.on('unhandledRejection', (err) => { console.log(err) })
7171
expect(getListenerCount()).toBe(1)
72-
72+
7373
unhandledRejectionMonitor.maybeRemoveListener()
7474
expect(getListenerCount()).toBe(1)
7575
})
7676
})
7777

78-
describe('__listener', () => {
78+
describe('__listener', () => {
7979
const promise = new Promise(() => true)
8080
const reason = 'Promise rejection reason'
8181

82-
it('calls notify and fatallyLogAndExit', (done) => {
82+
it('calls notify and fatallyLogAndExit', (done) => {
8383
unhandledRejectionMonitor.__listener(reason, promise)
8484
expect(notifySpy).toHaveBeenCalledTimes(1)
8585
expect(notifySpy).toHaveBeenCalledWith(
86-
reason,
86+
reason,
8787
{ component: 'unhandledRejection' },
8888
{ afterNotify: expect.any(Function) }
8989
)
9090
client.afterNotify(() => {
91-
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(reason)
91+
expect(fatallyLogAndExitSpy).toHaveBeenCalledWith(reason, 'unhandled rejection')
9292
done()
93-
})
93+
})
9494
})
9595
})
9696

0 commit comments

Comments
 (0)