Skip to content

Commit

Permalink
fix: Handle chunk load promise error introduced in 1.235.0 - NR-129244 (
Browse files Browse the repository at this point in the history
  • Loading branch information
cwli24 authored Jun 27, 2023
1 parent 72b22d6 commit a702e23
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/features/session_replay/replay-mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export async function getSessionReplayMode (agentId) {
const newrelic = gosNREUM()
// Should be enabled by configuration and using an agent build that includes it (via checking that the instrument class was initialized).
if (getConfigurationValue(agentId, 'session_replay.enabled') && typeof newrelic.initializedAgents[agentId].features.session_replay === 'object') {
await newrelic.initializedAgents[agentId].features.session_replay.onAggregateImported // if Replay could not initialize, this throws a (uncaught) rejection
return await sharedChannel.sessionReplayInitialized // wait for replay to determine which mode it's after running its sampling logic
const srInitialized = await newrelic.initializedAgents[agentId].features.session_replay.onAggregateImported
if (srInitialized) return await sharedChannel.sessionReplayInitialized // wait for replay to determine which mode it's after running its sampling logic
}
} catch (e) { /* exception ==> off */ }
return MODE.OFF // at any step of the way s.t. SR cannot be on by implication or is explicitly off
Expand Down
8 changes: 4 additions & 4 deletions src/features/utils/instrument-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export class InstrumentBase extends FeatureBase {
if (this.featAggregate || !this.auto) return
const enableSessionTracking = isBrowserScope && getConfigurationValue(this.agentIdentifier, 'privacy.cookies_enabled') === true
let loadedSuccessfully, loadFailed
this.onAggregateImported = new Promise((resolve, reject) => {
loadedSuccessfully = resolve; loadFailed = reject
this.onAggregateImported = new Promise(resolve => {
loadedSuccessfully = resolve
})

const importLater = async () => {
Expand All @@ -83,12 +83,12 @@ export class InstrumentBase extends FeatureBase {
const { lazyFeatureLoader } = await import(/* webpackChunkName: "lazy-feature-loader" */ './lazy-feature-loader')
const { Aggregate } = await lazyFeatureLoader(this.featureName, 'aggregate')
this.featAggregate = new Aggregate(this.agentIdentifier, this.aggregator, argsObjFromInstrument)
loadedSuccessfully()
loadedSuccessfully(true)
} catch (e) {
warn(`Downloading and initializing ${this.featureName} failed...`, e)
this.abortHandler?.() // undo any important alterations made to the page
// not supported yet but nice to do: "abort" this agent's EE for this feature specifically
loadFailed()
loadedSuccessfully(false)
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/features/utils/instrument-base.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ beforeEach(() => {
aggregator = {}
featureName = faker.datatype.uuid()

mockAggregate = jest.fn(() => { /* noop */ })
mockAggregate = jest.fn()
jest.mocked(lazyFeatureLoader).mockResolvedValue({ Aggregate: mockAggregate })
})

Expand Down Expand Up @@ -187,4 +187,23 @@ test('feature still imports by default even when setupAgentSession throws an err
expect(warn).toHaveBeenCalledWith(expect.stringContaining('A problem occurred when starting up session manager'), expect.any(Error))
expect(lazyFeatureLoader).toHaveBeenCalled()
expect(mockAggregate).toHaveBeenCalled()
await expect(instrument.onAggregateImported).resolves.toBe(true)
})

test('no uncaught async exception is thrown when an import fails', async () => {
jest.mocked(lazyFeatureLoader).mockRejectedValue(new Error('ChunkLoadError')) // () => { throw new Error('ChunkLoadError: loading chunk xxx failed.') })
const mockOnError = jest.fn()
global.onerror = mockOnError

const instrument = new InstrumentBase(agentIdentifier, aggregator, featureName)
instrument.abortHandler = jest.fn()
instrument.importAggregator()

const windowLoadCallback = jest.mocked(onWindowLoad).mock.calls[0][0]
await windowLoadCallback()

expect(warn).toHaveBeenNthCalledWith(2, expect.stringContaining(`Downloading and initializing ${featureName} failed`), expect.any(Error))
expect(instrument.abortHandler).toHaveBeenCalled()
await expect(instrument.onAggregateImported).resolves.toBe(false)
expect(mockOnError).not.toHaveBeenCalled()
})

0 comments on commit a702e23

Please sign in to comment.