Skip to content

Commit

Permalink
support error context
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanGaignault committed Feb 4, 2025
1 parent 46cc11a commit aacc3ec
Show file tree
Hide file tree
Showing 15 changed files with 95 additions and 6 deletions.
13 changes: 13 additions & 0 deletions packages/core/src/domain/console/consoleObservable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,17 @@ describe('console error observable', () => {
const consoleLog = notifyLog.calls.mostRecent().args[0]
expect(consoleLog.error.fingerprint).toBe('2')
})

it('should retrieve context from error', () => {
interface DatadogError extends Error {
dd_context?: Record<string, unknown>
}
const error = new Error('foo')
;(error as DatadogError).dd_context = { foo: 'bar' }

console.error(error)

const consoleLog = notifyLog.calls.mostRecent().args[0]
expect(consoleLog.error.context).toEqual({ foo: 'bar' })
})
})
3 changes: 2 additions & 1 deletion packages/core/src/domain/console/consoleObservable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { flattenErrorCauses, isError, tryToGetFingerprint } from '../error/error'
import { flattenErrorCauses, isError, tryToGetFingerprint, tryToGetErrorContext } from '../error/error'
import { mergeObservables, Observable } from '../../tools/observable'
import { ConsoleApiName, globalConsole } from '../../tools/display'
import { callMonitored } from '../../tools/monitor'
Expand Down Expand Up @@ -84,6 +84,7 @@ function buildConsoleLog(params: unknown[], api: ConsoleApiName, handlingStack:
source: ErrorSource.CONSOLE,
handling: ErrorHandling.HANDLED,
handlingStack,
context: tryToGetErrorContext(firstErrorParam),
}
}

Expand Down
20 changes: 16 additions & 4 deletions packages/core/src/domain/error/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function computeRawError({
const causes = isErrorInstance ? flattenErrorCauses(originalError as ErrorWithCause, source) : undefined
const type = stackTrace ? stackTrace.name : undefined
const fingerprint = tryToGetFingerprint(originalError)
const context = isErrorInstance ? tryToGetErrorContext(originalError) : undefined

return {
startClocks,
Expand All @@ -52,6 +53,7 @@ export function computeRawError({
stack,
causes,
fingerprint,
context,
}
}

Expand Down Expand Up @@ -86,6 +88,13 @@ export function tryToGetFingerprint(originalError: unknown) {
return isError(originalError) && 'dd_fingerprint' in originalError ? String(originalError.dd_fingerprint) : undefined
}

export function tryToGetErrorContext(originalError: unknown) {
if (isError(originalError) && 'dd_context' in originalError) {
return originalError.dd_context as Record<string, unknown>
}
return undefined
}

export function getFileFromStackTraceString(stack: string) {
return /@ (.+)/.exec(stack)?.[1]
}
Expand All @@ -98,14 +107,17 @@ export function flattenErrorCauses(error: ErrorWithCause, parentSource: ErrorSou
let currentError = error
const causes: RawErrorCause[] = []
while (isError(currentError?.cause) && causes.length < 10) {
const stackTrace = computeStackTrace(currentError.cause)
const causeError = currentError.cause
const stackTrace = computeStackTrace(causeError)

causes.push({
message: currentError.cause.message,
message: causeError.message,
source: parentSource,
type: stackTrace?.name,
stack: stackTrace && toStackTraceString(stackTrace),
stack: stackTrace ? toStackTraceString(stackTrace) : NO_ERROR_STACK_PRESENT_MESSAGE,
context: tryToGetErrorContext(causeError),
})
currentError = currentError.cause
currentError = causeError
}
return causes.length ? causes : undefined
}
2 changes: 2 additions & 0 deletions packages/core/src/domain/error/error.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type RawErrorCause = {
source: string
type?: string
stack?: string
context?: Record<string, unknown>
}

export type Csp = {
Expand All @@ -37,6 +38,7 @@ export interface RawError {
causes?: RawErrorCause[]
fingerprint?: string
csp?: Csp
context?: Record<string, unknown>
}

export const ErrorSource = {
Expand Down
30 changes: 30 additions & 0 deletions packages/logs/src/domain/console/consoleCollection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ describe('console collection', () => {
expect(rawLogsEvents[0].rawLogsEvent.error).toEqual({
stack: undefined,
fingerprint: undefined,
context: undefined,
causes: undefined,
handling: ErrorHandling.HANDLED,
kind: undefined,
Expand Down Expand Up @@ -99,6 +100,32 @@ describe('console collection', () => {
handling: ErrorHandling.HANDLED,
kind: undefined,
message: undefined,
context: undefined,
})
})

it('should retrieve context from console error', () => {
;({ stop: stopConsoleCollection } = startConsoleCollection(
validateAndBuildLogsConfiguration({ ...initConfiguration, forwardErrorsToLogs: true })!,
lifeCycle
))
interface DatadogError extends Error {
dd_context?: Record<string, unknown>
}
const error = new Error('foo')
;(error as DatadogError).dd_context = { foo: 'bar' }

// eslint-disable-next-line no-console
console.error(error)

expect(rawLogsEvents[0].rawLogsEvent.error).toEqual({
stack: jasmine.any(String),
fingerprint: undefined,
causes: undefined,
handling: ErrorHandling.HANDLED,
kind: undefined,
message: undefined,
context: { foo: 'bar' },
})
})

Expand Down Expand Up @@ -131,15 +158,18 @@ describe('console collection', () => {
type: 'Error',
stack: jasmine.any(String),
message: 'Mid level error',
context: undefined,
},
{
source: ErrorSource.CONSOLE,
type: 'TypeError',
stack: jasmine.any(String),
message: 'Low level error',
context: undefined,
},
],
fingerprint: undefined,
context: undefined,
kind: undefined,
message: undefined,
})
Expand Down
6 changes: 6 additions & 0 deletions packages/logs/src/domain/createErrorFieldFromRawError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ describe('createErrorFieldFromRawError', () => {
csp: {
disposition: 'enforce',
},
context: {
grault: 'garply',
},
}

it('creates an error field from a raw error', () => {
Expand All @@ -30,6 +33,9 @@ describe('createErrorFieldFromRawError', () => {
causes: [],
fingerprint: 'corge',
handling: ErrorHandling.HANDLED,
context: {
grault: 'garply',
},
})
})

Expand Down
1 change: 1 addition & 0 deletions packages/logs/src/domain/createErrorFieldFromRawError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function createErrorFieldFromRawError(
message: includeMessage ? rawError.message : undefined,
causes: rawError.causes,
fingerprint: rawError.fingerprint,
context: rawError.context,
handling: rawError.handling,
}
}
14 changes: 13 additions & 1 deletion packages/logs/src/domain/logger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('Logger', () => {
causes: undefined,
handling: ErrorHandling.HANDLED,
fingerprint: undefined,
context: undefined,
},
})
})
Expand Down Expand Up @@ -116,6 +117,7 @@ describe('Logger', () => {
causes: undefined,
handling: ErrorHandling.HANDLED,
fingerprint: undefined,
context: undefined,
},
},
status: 'error',
Expand Down Expand Up @@ -158,15 +160,23 @@ describe('Logger', () => {
message: 'High level error',
handling: ErrorHandling.HANDLED,
causes: [
{ message: 'Mid level error', source: 'logger', type: 'Error', stack: 'Error: Mid level error' },
{
message: 'Mid level error',
source: 'logger',
type: 'Error',
stack: 'Error: Mid level error',
context: undefined,
},
{
message: 'Low level error',
source: 'logger',
type: 'TypeError',
stack: 'TypeError: Low level error',
context: undefined,
},
],
fingerprint: undefined,
context: undefined,
},
},
})
Expand Down Expand Up @@ -263,6 +273,7 @@ describe('Logger', () => {
causes: undefined,
handling: ErrorHandling.HANDLED,
fingerprint: undefined,
context: undefined,
})
})

Expand All @@ -279,6 +290,7 @@ describe('Logger', () => {
causes: undefined,
handling: ErrorHandling.HANDLED,
fingerprint: undefined,
context: undefined,
})
})

Expand Down
1 change: 1 addition & 0 deletions packages/logs/src/domain/report/reportCollection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe('reports', () => {
causes: undefined,
fingerprint: undefined,
message: undefined,
context: undefined,
},
date: jasmine.any(Number),
message: 'intervention: foo bar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe('runtime error collection', () => {
handling: ErrorHandling.UNHANDLED,
fingerprint: undefined,
message: undefined,
context: undefined,
},
message: 'error!',
status: StatusType.error,
Expand Down Expand Up @@ -87,16 +88,19 @@ describe('runtime error collection', () => {
type: 'Error',
stack: jasmine.any(String),
message: 'Mid level error',
context: undefined,
},
{
source: ErrorSource.SOURCE,
type: 'TypeError',
stack: jasmine.any(String),
message: 'Low level error',
context: undefined,
},
],
fingerprint: undefined,
message: undefined,
context: undefined,
},
message: 'High level error',
status: StatusType.error,
Expand Down
1 change: 1 addition & 0 deletions packages/logs/src/rawLogsEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Error = {
kind?: string
stack?: string
fingerprint?: string
context?: Record<string, unknown>
causes?: RawErrorCause[]
handling: ErrorHandling | undefined
}
Expand Down
2 changes: 2 additions & 0 deletions packages/rum-core/src/domain/error/errorCollection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('error collection', () => {
causes: undefined,
fingerprint: undefined,
csp: undefined,
context: undefined,
},
type: RumEventType.ERROR,
view: {
Expand Down Expand Up @@ -269,6 +270,7 @@ describe('error collection', () => {
causes: undefined,
fingerprint: undefined,
csp: undefined,
context: undefined,
},
view: {
in_foreground: true,
Expand Down
1 change: 1 addition & 0 deletions packages/rum-core/src/domain/error/errorCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function processError(error: RawError, pageStateHistory: PageStateHistory): RawR
source_type: 'browser',
fingerprint: error.fingerprint,
csp: error.csp,
context: error.context,
},
type: RumEventType.ERROR as const,
view: { in_foreground: pageStateHistory.wasInPageStateAt(PageState.ACTIVE, error.startClocks.relative) },
Expand Down
2 changes: 2 additions & 0 deletions packages/rum-core/src/domain/error/trackConsoleError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('trackConsoleError', () => {
message: jasmine.any(String),
stack: jasmine.any(String),
fingerprint: undefined,
context: undefined,
source: ErrorSource.CONSOLE,
handling: ErrorHandling.HANDLED,
handlingStack: jasmine.any(String),
Expand All @@ -60,6 +61,7 @@ describe('trackConsoleError', () => {
handlingStack: jasmine.any(String),
fingerprint: 'my-fingerprint',
causes: undefined,
context: undefined,
})
})
})
1 change: 1 addition & 0 deletions packages/rum-core/src/rawRumEvent.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export interface RawRumErrorEvent {
causes?: RawErrorCause[]
source_type: 'browser'
csp?: Csp
context?: Record<string, unknown>
}
view?: {
in_foreground: boolean
Expand Down

0 comments on commit aacc3ec

Please sign in to comment.