Skip to content

Commit b7f5f27

Browse files
committed
Allow overriding unhandled state in callbacks
1 parent 08c3602 commit b7f5f27

File tree

3 files changed

+107
-8
lines changed

3 files changed

+107
-8
lines changed

packages/core/client.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,18 @@ class Client {
273273
event._user = assign({}, event._user, this._user)
274274
event.breadcrumbs = this._breadcrumbs.slice()
275275

276-
if (this._session) {
277-
this._session._track(event)
278-
event._session = this._session
276+
const trackSession = event => {
277+
if (this._session) {
278+
this._session._track(event)
279+
event._session = this._session
280+
}
279281
}
280282

281283
// exit early if events should not be sent on the current releaseStage
282284
if (this._config.enabledReleaseStages !== null && !includes(this._config.enabledReleaseStages, this._config.releaseStage)) {
283285
this._logger.warn('Event not sent due to releaseStage/enabledReleaseStages configuration')
286+
trackSession(event)
287+
284288
return cb(null, event)
285289
}
286290

@@ -298,6 +302,8 @@ class Client {
298302

299303
if (!shouldSend) {
300304
this._logger.debug('Event not sent due to onError callback')
305+
trackSession(event)
306+
301307
return cb(null, event)
302308
}
303309

@@ -314,6 +320,13 @@ class Client {
314320
event._handledState.severityReason = { type: 'userCallbackSetSeverity' }
315321
}
316322

323+
if (event.unhandled !== event._handledState.unhandled) {
324+
event._handledState.severityReason.unhandledOverridden = true
325+
event._handledState.unhandled = event.unhandled
326+
}
327+
328+
trackSession(event)
329+
317330
this._delivery.sendEvent({
318331
apiKey: event.apiKey || this._config.apiKey,
319332
notifier: this._notifier,

packages/core/session.d.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Session from './types/session'
2+
3+
interface MinimalEvent {
4+
_handledState: {
5+
unhandled: boolean
6+
}
7+
}
8+
9+
interface SessionJson {
10+
id: string
11+
startedAt: Date
12+
events: {
13+
handled: number
14+
unhandled: number
15+
}
16+
}
17+
18+
export default class SessionWithInternals extends Session {
19+
_track(event: MinimalEvent): void
20+
toJSON(): SessionJson
21+
22+
public _handled: number
23+
public _unhandled: number
24+
}

packages/core/test/client.test.ts

+67-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Client from '../client'
22
import Event from '../event'
3-
import { Session } from '..'
3+
import Session from '../session'
44

55
describe('@bugsnag/core/client', () => {
66
describe('constructor', () => {
@@ -158,6 +158,41 @@ describe('@bugsnag/core/client', () => {
158158
event.severity = 'info'
159159
})
160160
})
161+
162+
it('supports setting unhandled via callback', done => {
163+
const client = new Client({ apiKey: 'API_KEY_YEAH' })
164+
165+
const session = new Session()
166+
// @ts-ignore
167+
client._session = session
168+
169+
client._setDelivery(client => ({
170+
sendEvent: (payload) => {
171+
expect(payload).toBeTruthy()
172+
expect(Array.isArray(payload.events)).toBe(true)
173+
174+
const event = payload.events[0].toJSON()
175+
176+
expect(event.unhandled).toBe(true)
177+
expect(event.severityReason).toEqual({
178+
type: 'handledException',
179+
unhandledOverridden: true
180+
})
181+
182+
expect(event.session).toEqual(session)
183+
expect((event.session as Session)._handled).toBe(0)
184+
expect((event.session as Session)._unhandled).toBe(1)
185+
186+
done()
187+
},
188+
sendSession: () => {}
189+
}))
190+
191+
client.notify(new Error('oh em gee'), event => {
192+
event.unhandled = true
193+
})
194+
})
195+
161196
// eslint-disable-next-line jest/expect-expect
162197
it('supports preventing send by returning false in onError callback', done => {
163198
const client = new Client({
@@ -177,6 +212,7 @@ describe('@bugsnag/core/client', () => {
177212
// give the event loop a tick to see if the event gets sent
178213
process.nextTick(() => done())
179214
})
215+
180216
// eslint-disable-next-line jest/expect-expect
181217
it('supports preventing send by returning false in notify callback', done => {
182218
const client = new Client({ apiKey: 'API_KEY_YEAH' })
@@ -355,11 +391,18 @@ describe('@bugsnag/core/client', () => {
355391
sendSession: () => {},
356392
sendEvent: (payload, cb) => cb(null)
357393
}))
394+
395+
const session = new Session()
358396
// @ts-ignore
359-
client.notify(new Error('111'), {}, (err, event) => {
397+
client._session = session
398+
399+
client.notify(new Error('111'), () => {}, (err, event) => {
360400
expect(err).toBe(null)
361401
expect(event).toBeTruthy()
362402
expect(event.errors[0].errorMessage).toBe('111')
403+
404+
expect((event as Event)._session).toBe(session)
405+
expect(session.toJSON().events.handled).toBe(1)
363406
done()
364407
})
365408
})
@@ -370,12 +413,19 @@ describe('@bugsnag/core/client', () => {
370413
sendSession: () => {},
371414
sendEvent: (payload, cb) => cb(new Error('flerp'))
372415
}))
416+
417+
const session = new Session()
373418
// @ts-ignore
374-
client.notify(new Error('111'), {}, (err, event) => {
419+
client._session = session
420+
421+
client.notify(new Error('111'), () => {}, (err, event) => {
375422
expect(err).toBeTruthy()
376423
expect(err.message).toBe('flerp')
377424
expect(event).toBeTruthy()
378425
expect(event.errors[0].errorMessage).toBe('111')
426+
427+
expect((event as Event)._session).toBe(session)
428+
expect(session.toJSON().events.handled).toBe(1)
379429
done()
380430
})
381431
})
@@ -388,11 +438,17 @@ describe('@bugsnag/core/client', () => {
388438
sendEvent: () => { done('sendEvent() should not be called') }
389439
}))
390440

441+
const session = new Session()
391442
// @ts-ignore
392-
client.notify(new Error('111'), {}, (err, event) => {
443+
client._session = session
444+
445+
client.notify(new Error('111'), () => {}, (err, event) => {
393446
expect(err).toBe(null)
394447
expect(event).toBeTruthy()
395448
expect(event.errors[0].errorMessage).toBe('111')
449+
450+
expect((event as Event)._session).toBe(session)
451+
expect(session.toJSON().events.handled).toBe(1)
396452
done()
397453
})
398454
})
@@ -405,11 +461,17 @@ describe('@bugsnag/core/client', () => {
405461
sendEvent: () => { done('sendEvent() should not be called') }
406462
}))
407463

464+
const session = new Session()
408465
// @ts-ignore
409-
client.notify(new Error('111'), {}, (err, event) => {
466+
client._session = session
467+
468+
client.notify(new Error('111'), () => {}, (err, event) => {
410469
expect(err).toBe(null)
411470
expect(event).toBeTruthy()
412471
expect(event.errors[0].errorMessage).toBe('111')
472+
473+
expect((event as Event)._session).toBe(session)
474+
expect(session.toJSON().events.handled).toBe(1)
413475
done()
414476
})
415477
})

0 commit comments

Comments
 (0)