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
1 change: 1 addition & 0 deletions packages/core/src/tools/experimentalFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export enum ExperimentalFeature {
SHORT_SESSION_INVESTIGATION = 'short_session_investigation',
AVOID_FETCH_KEEPALIVE = 'avoid_fetch_keepalive',
USE_CHANGE_RECORDS = 'use_change_records',
SOURCE_CODE_CONTEXT = 'source_code_context',
}

const enabledExperimentalFeatures: Set<ExperimentalFeature> = new Set()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@ export const CHROME_111_SNIPPET = {
at snippet:///snippet_file:1:13`,
}

export const CHROME_141_HTML_ANONYMOUS_LISTENER = {
message: 'message string',
name: 'Error',
stack: `Error: message string
at HTMLButtonElement.<anonymous> @ http://path/to/file.js:1:4287`,
}

export const PHANTOMJS_1_19 = {
stack: `Error: foo
at file:///path/to/file.js:878
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/tools/stackTrace/computeStackTrace.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { isSafari } from '../utils/browserDetection'
import * as CapturedExceptions from './capturedExceptions.specHelper'
import { CHROME_141_HTML_ANONYMOUS_LISTENER } from './capturedExceptions.specHelper'
import { computeStackTrace } from './computeStackTrace'

describe('computeStackTrace', () => {
Expand Down Expand Up @@ -1004,4 +1005,17 @@ Error: foo
column: undefined,
})
})

it('should parse stack from html button click listener', () => {
const stackFrames = computeStackTrace(CHROME_141_HTML_ANONYMOUS_LISTENER)

expect(stackFrames.stack.length).toEqual(1)
expect(stackFrames.stack[0]).toEqual({
args: [],
column: 4287,
func: 'HTMLButtonElement.<anonymous>',
line: 1,
url: 'http://path/to/file.js',
})
})
})
14 changes: 9 additions & 5 deletions packages/core/src/tools/stackTrace/computeStackTrace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ function parseChromeLine(line: string): StackFrame | undefined {
}
}

const CHROME_ANONYMOUS_FUNCTION_RE = new RegExp(`^\\s*at ?${fileUrl}${filePosition}?${filePosition}??\\s*$`, 'i')
const htmlAnonymousPart = '(?:(.*)?(?: @))'
const CHROME_ANONYMOUS_FUNCTION_RE = new RegExp(
`^\\s*at\\s*${htmlAnonymousPart}?\\s*${fileUrl}${filePosition}?${filePosition}??\\s*$`,
'i'
)

function parseChromeAnonymousLine(line: string): StackFrame | undefined {
const parts = CHROME_ANONYMOUS_FUNCTION_RE.exec(line)
Expand All @@ -124,10 +128,10 @@ function parseChromeAnonymousLine(line: string): StackFrame | undefined {

return {
args: [],
column: parts[3] ? +parts[3] : undefined,
func: UNKNOWN_FUNCTION,
line: parts[2] ? +parts[2] : undefined,
url: parts[1],
column: parts[4] ? +parts[4] : undefined,
func: parts[1] || UNKNOWN_FUNCTION,
line: parts[3] ? +parts[3] : undefined,
url: parts[2],
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/rum-core/src/boot/startRum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import type { Hooks } from '../domain/hooks'
import { createHooks } from '../domain/hooks'
import { startEventCollection } from '../domain/event/eventCollection'
import { startInitialViewMetricsTelemetry } from '../domain/view/viewMetrics/startInitialViewMetricsTelemetry'
import { startSourceCodeContext } from '../domain/contexts/sourceCodeContext'
import type { RecorderApi, ProfilerApi } from './rumPublicApi'

export type StartRum = typeof startRum
Expand Down Expand Up @@ -230,6 +231,9 @@ export function startRumEventCollection(
viewHistory,
initialViewOptions
)

startSourceCodeContext(hooks)

cleanupTasks.push(stopViewCollection)

const { stop: stopResourceCollection } = startResourceCollection(lifeCycle, configuration, pageStateHistory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { RawRumActionEvent, RawRumEvent } from '../../rawRumEvent.types'
import { RumEventType, ActionType } from '../../rawRumEvent.types'
import type { RawRumEventCollectedData } from '../lifeCycle'
import { LifeCycle, LifeCycleEventType } from '../lifeCycle'
import type { DefaultTelemetryEventAttributes, Hooks } from '../hooks'
import type { AssembleHookParams, DefaultTelemetryEventAttributes, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import type { RumMutationRecord } from '../../browser/domMutationObservable'
import type { ActionContexts } from './actionCollection'
Expand Down Expand Up @@ -174,7 +174,7 @@ describe('actionCollection', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType,
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({ type: eventType, action: { id: actionId } })
})
Expand All @@ -186,7 +186,7 @@ describe('actionCollection', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType,
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual(undefined)
})
Expand All @@ -200,7 +200,7 @@ describe('actionCollection', () => {
eventType: RumEventType.LONG_TASK,
startTime: longTaskStartTime,
duration: 50 as Duration,
})
} as AssembleHookParams)

const [correctedStartTime] = findActionIdSpy.calls.mostRecent().args
expect(correctedStartTime).toEqual(addDuration(longTaskStartTime, LONG_TASK_START_TIME_CORRECTION))
Expand Down
6 changes: 4 additions & 2 deletions packages/rum-core/src/domain/assembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { LifeCycleEventType } from './lifeCycle'
import type { RumConfiguration } from './configuration'
import type { ModifiableFieldPaths } from './limitModification'
import { limitModification } from './limitModification'
import type { Hooks } from './hooks'
import type { Hooks, AssembleHookParams } from './hooks'

const VIEW_MODIFIABLE_FIELD_PATHS: ModifiableFieldPaths = {
'view.name': 'string',
Expand Down Expand Up @@ -95,9 +95,11 @@ export function startRumAssembly(
({ startTime, duration, rawRumEvent, domainContext }) => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: rawRumEvent.type,
rawRumEvent,
domainContext,
startTime,
duration,
})!
} as AssembleHookParams)!

if (defaultRumEventAttributes === DISCARDED) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { HookNames, Observable } from '@datadog/browser-core'
import { mockCiVisibilityValues } from '../../../test'
import type { CookieObservable } from '../../browser/cookieObservable'
import { SessionType } from '../rumSessionManager'
import type { Hooks } from '../hooks'
import type { AssembleHookParams, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import { startCiVisibilityContext } from './ciVisibilityContext'

Expand All @@ -29,7 +29,7 @@ describe('startCiVisibilityContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: 'view',
Expand All @@ -49,7 +49,7 @@ describe('startCiVisibilityContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: 'view',
Expand All @@ -70,7 +70,7 @@ describe('startCiVisibilityContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: 'view',
Expand All @@ -90,7 +90,7 @@ describe('startCiVisibilityContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toBeUndefined()
})
Expand All @@ -102,7 +102,7 @@ describe('startCiVisibilityContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toBeUndefined()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { setNavigatorOnLine, setNavigatorConnection } from '@datadog/browser-core/test'
import { HookNames } from '@datadog/browser-core'
import type { RelativeTime } from '@datadog/browser-core'
import type { Hooks } from '../hooks'
import type { AssembleHookParams, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import { startConnectivityContext } from './connectivityContext'

Expand All @@ -17,7 +17,10 @@ describe('startConnectivityContext', () => {
startConnectivityContext(hooks)
setNavigatorOnLine(true)
setNavigatorConnection({ effectiveType: '2g' })
const event = hooks.triggerHook(HookNames.Assemble, { eventType: 'view', startTime: 0 as RelativeTime })
const event = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
} as AssembleHookParams)

expect(event).toEqual({
type: 'view',
Expand Down
10 changes: 5 additions & 5 deletions packages/rum-core/src/domain/contexts/defaultContext.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { mockClock, mockEventBridge } from '@datadog/browser-core/test'
import { HookNames, timeStampNow } from '@datadog/browser-core'
import type { RelativeTime } from '@datadog/browser-core'
import { mockRumConfiguration } from '../../../test'
import type { DefaultRumEventAttributes, DefaultTelemetryEventAttributes, Hooks } from '../hooks'
import type { AssembleHookParams, DefaultRumEventAttributes, DefaultTelemetryEventAttributes, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import { startDefaultContext } from './defaultContext'

Expand All @@ -20,7 +20,7 @@ describe('startDefaultContext', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: 'view',
Expand All @@ -41,14 +41,14 @@ describe('startDefaultContext', () => {
const eventWithoutEventBridge = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
}) as DefaultRumEventAttributes
} as AssembleHookParams) as DefaultRumEventAttributes

mockEventBridge()

const eventWithEventBridge = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
}) as DefaultRumEventAttributes
} as AssembleHookParams) as DefaultRumEventAttributes

expect(eventWithEventBridge._dd!.browser_sdk_version).toBeDefined()
expect(eventWithoutEventBridge._dd!.browser_sdk_version).toBeUndefined()
Expand All @@ -64,7 +64,7 @@ describe('startDefaultContext', () => {
const event = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
}) as DefaultRumEventAttributes
} as AssembleHookParams) as DefaultRumEventAttributes

expect(event._dd!.configuration!.session_sample_rate).toBe(10)
expect(event._dd!.configuration!.session_replay_sample_rate).toBe(20)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HookNames } from '@datadog/browser-core'
import type { RelativeTime } from '@datadog/browser-core'
import { mockRumConfiguration } from '../../../test'
import type { Hooks } from '../hooks'
import type { AssembleHookParams, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import type { DisplayContext } from './displayContext'
import { startDisplayContext } from './displayContext'
Expand All @@ -27,7 +27,10 @@ describe('displayContext', () => {
it('should set the display context', () => {
displayContext = startDisplayContext(hooks, mockRumConfiguration())

const event = hooks.triggerHook(HookNames.Assemble, { eventType: 'view', startTime: 0 as RelativeTime })
const event = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
} as AssembleHookParams)
expect(requestAnimationFrameSpy).toHaveBeenCalledTimes(1)

expect(event).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LifeCycle, LifeCycleEventType } from '../lifeCycle'
import type { ViewCreatedEvent, ViewEndedEvent } from '../view/trackViews'
import type { RumConfiguration } from '../configuration'
import { RumEventType } from '../../rawRumEvent.types'
import type { Hooks } from '../hooks'
import type { AssembleHookParams, Hooks } from '../hooks'
import { createHooks } from '../hooks'
import type { FeatureFlagContexts } from './featureFlagContext'
import { startFeatureFlagContexts } from './featureFlagContext'
Expand Down Expand Up @@ -38,11 +38,11 @@ describe('featureFlagContexts', () => {
const defaultViewAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)
const defaultErrorAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'error',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultViewAttributes).toEqual({
type: 'view',
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('featureFlagContexts', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType,
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: eventType,
Expand All @@ -94,7 +94,7 @@ describe('featureFlagContexts', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({
type: 'view',
Expand Down Expand Up @@ -127,11 +127,11 @@ describe('featureFlagContexts', () => {
const defaultEventOneAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 5 as RelativeTime,
})
} as AssembleHookParams)
const defaultEventTwoAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 15 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultEventOneAttributes).toEqual({ type: 'view', feature_flags: { feature: 'one' } })
expect(defaultEventTwoAttributes).toEqual({ type: 'view', feature_flags: { feature: 'two' } })
Expand All @@ -149,7 +149,7 @@ describe('featureFlagContexts', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toBeUndefined()
})
Expand All @@ -166,7 +166,7 @@ describe('featureFlagContexts', () => {
const defaultRumEventAttributes = hooks.triggerHook(HookNames.Assemble, {
eventType: 'view',
startTime: 0 as RelativeTime,
})
} as AssembleHookParams)

expect(defaultRumEventAttributes).toEqual({ type: 'view', feature_flags: { feature: 'bar', feature2: 'baz' } })
})
Expand Down
Loading