Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/features/jserrors/aggregate/format-stack-trace.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2020-2025 New Relic, Inc. All rights reserved.
* Copyright 2020-2026 New Relic, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

Expand All @@ -10,7 +10,7 @@ export function formatStackTrace (stackLines) {
return truncateStackLines(stackLines).replace(stripNewlinesRegex, '')
}

// takes array of stack lines and returns string with top 50 and buttom 50 lines
// takes array of stack lines and returns string with top 50 and bottom 50 lines
function truncateStackLines (stackLines) {
var stackString
if (stackLines.length > 100) {
Expand All @@ -26,5 +26,5 @@ function truncateStackLines (stackLines) {

// truncates stack string to limit what is sent to backend
export function truncateSize (stackString) {
return (stackString.length > MAX_STACK_TRACE_LENGTH) ? stackString.substr(0, MAX_STACK_TRACE_LENGTH) : stackString
return stackString.length > MAX_STACK_TRACE_LENGTH ? stackString.substr(0, MAX_STACK_TRACE_LENGTH) : stackString
}
2 changes: 1 addition & 1 deletion src/features/jserrors/aggregate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export class Aggregate extends AggregateBase {
params.stack_trace = truncateSize(stackInfo.stackString)
this.observedAt[bucketHash] = Math.floor(this.agentRef.runtime.timeKeeper.correctRelativeTimestamp(time))
} else {
params.browser_stack_hash = stringHashCode(stackInfo.stackString)
params.browser_stack_hash = stringHashCode(truncateSize(stackInfo.stackString))
}
params.releaseIds = stringify(this.agentRef.runtime.releaseIds)

Expand Down
61 changes: 61 additions & 0 deletions tests/components/jserrors/browser-stack-hash.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { stringHashCode } from '../../../src/features/jserrors/aggregate/string-hash-code'
import { Instrument as JsErrors } from '../../../src/features/jserrors/instrument'
import { resetAgent, setupAgent } from '../setup-agent'

let mainAgent
beforeAll(() => {
mainAgent = setupAgent({
init: {
jserrors: { enabled: true }
}
})
})

let jserrorsAggregate
beforeEach(async () => {
const jserrorsInstrument = new JsErrors(mainAgent)
await Promise.all([jserrorsInstrument.onAggregateImported])
jserrorsAggregate = jserrorsInstrument.featAggregate

jserrorsAggregate.ee.emit('rumresp', [{ err: 1 }]) // register rumresp event to activate and drain error buffer
await new Promise(process.nextTick)
})
afterEach(() => {
resetAgent(mainAgent)
})

// This function will generate an error with a stack trace that is larger than the maximum size allowed for the stack trace string
const generateTestError = (errorName) => {
const maxSize = 65530
const error = new Error(errorName)
const stackHeader = error.stack.split('\n')[0]
const stackLines = [stackHeader]
let i = 0
while (stackLines.join('\n').length < maxSize + 100) {
stackLines.push(` at generated${'F'.repeat(maxSize / 100)}rame (https://example.com/app.js:1:${i})`)
i++
}

error.stack = stackLines.join('\n')
return error
}

test('in error params, string hash code of max-sized stack trace equals browser stack hash', async () => {
let harvestedData

await new Promise(process.nextTick)
jserrorsAggregate.processError(generateTestError('test message'), 100) // emit an error with max-sized stack trace

harvestedData = jserrorsAggregate.events.get(jserrorsAggregate.harvestOpts)
const stack_trace = harvestedData.err[0].params.stack_trace // get the stack trace

jserrorsAggregate.events.clear() // pretend that we drained the data by clearing the buffer; needed to get browser stack hash

await new Promise(process.nextTick)
jserrorsAggregate.processError(generateTestError('test message'), 101) // emit the same error again

harvestedData = jserrorsAggregate.events.get(jserrorsAggregate.harvestOpts)
const browser_stack_hash = harvestedData.err[0].params.browser_stack_hash // get the browser stack hash

expect(stringHashCode(stack_trace)).toEqual(browser_stack_hash) // string hashed stack_trace must equal browser_stack_hash
})
Loading