Skip to content

Commit c987364

Browse files
committed
🐛 add support for arbitrary causes
1 parent acb54dc commit c987364

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

packages/core/src/domain/error/error.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
isError,
99
NO_ERROR_STACK_PRESENT_MESSAGE,
1010
} from './error'
11-
import type { RawErrorCause, ErrorWithCause } from './error.types'
11+
import type { ErrorWithCause, RawFlatErrorCause } from './error.types'
1212
import { ErrorHandling, ErrorSource, NonErrorPrefix } from './error.types'
1313

1414
describe('computeRawError', () => {
@@ -179,7 +179,7 @@ describe('computeRawError', () => {
179179
expect(formatted.causes!.length).toBe(2)
180180
expect(formatted.stack).toContain('Error: foo: bar')
181181

182-
const causes = formatted.causes as RawErrorCause[]
182+
const causes = formatted.causes as RawFlatErrorCause[]
183183

184184
expect(causes[0].message).toContain(nestedError.message)
185185
expect(causes[0].source).toContain(ErrorSource.SOURCE)
@@ -250,7 +250,7 @@ describe('flattenErrorCauses', () => {
250250
error.cause = new Error('bar')
251251

252252
const errorCauses = flattenErrorCauses(error, ErrorSource.LOGGER)
253-
expect(errorCauses?.[0].type).toEqual('Error')
253+
expect((errorCauses?.[0] as RawFlatErrorCause).type).toEqual('Error')
254254
})
255255

256256
it('should only return the first 10 errors if nested chain is longer', () => {

packages/core/src/domain/error/error.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ import { jsonStringify } from '../../tools/serialisation/jsonStringify'
55
import type { StackTrace } from '../../tools/stackTrace/computeStackTrace'
66
import { computeStackTrace } from '../../tools/stackTrace/computeStackTrace'
77
import { toStackTraceString } from '../../tools/stackTrace/handlingStack'
8-
import type { ErrorSource, ErrorHandling, RawError, RawErrorCause, ErrorWithCause, NonErrorPrefix } from './error.types'
8+
import type {
9+
ErrorSource,
10+
ErrorHandling,
11+
RawError,
12+
RawErrorCause,
13+
ErrorWithCause,
14+
NonErrorPrefix,
15+
RawFlatErrorCause,
16+
} from './error.types'
917

1018
export const NO_ERROR_STACK_PRESENT_MESSAGE = 'No stack, consider using an instance of Error'
1119

@@ -87,17 +95,26 @@ export function isError(error: unknown): error is Error {
8795
}
8896

8997
export function flattenErrorCauses(error: ErrorWithCause, parentSource: ErrorSource): RawErrorCause[] | undefined {
90-
let currentError = error
9198
const causes: RawErrorCause[] = []
92-
while (isError(currentError?.cause) && causes.length < 10) {
93-
const stackTrace = computeStackTrace(currentError.cause)
94-
causes.push({
95-
message: currentError.cause.message,
96-
source: parentSource,
97-
type: stackTrace?.name,
98-
stack: stackTrace && toStackTraceString(stackTrace),
99-
})
100-
currentError = currentError.cause
99+
100+
let currentCause = error.cause
101+
while (currentCause !== undefined && currentCause !== null && causes.length < 10) {
102+
if (isError(currentCause)) {
103+
const stackTrace = computeStackTrace(currentCause)
104+
105+
causes.push({
106+
message: currentCause.message,
107+
source: parentSource,
108+
type: stackTrace?.name,
109+
stack: stackTrace && toStackTraceString(stackTrace),
110+
} satisfies RawFlatErrorCause)
111+
112+
currentCause = (currentCause as ErrorWithCause).cause
113+
} else {
114+
causes.push(currentCause)
115+
116+
currentCause = undefined
117+
}
101118
}
102119
return causes.length ? causes : undefined
103120
}

packages/core/src/domain/error/error.types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ export interface ErrorWithCause extends Omit<Error, 'cause'> {
1414
cause?: unknown
1515
}
1616

17-
export interface RawErrorCause {
17+
export type RawErrorCause = unknown
18+
19+
export interface RawFlatErrorCause {
1820
message: string
1921
source: ErrorSource
2022
type?: string

packages/rum-core/src/domain/error/errorCollection.spec.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { RelativeTime, TimeStamp, ErrorWithCause } from '@datadog/browser-core'
22
import { ErrorHandling, ErrorSource, NO_ERROR_STACK_PRESENT_MESSAGE } from '@datadog/browser-core'
33
import { FAKE_CSP_VIOLATION_EVENT } from '@datadog/browser-core/test'
4+
import type { RawFlatErrorCause } from '@datadog/browser-core/src/domain/error/error.types.ts'
45
import { collectAndValidateRawRumEvents } from '../../../test'
56
import type { RawRumErrorEvent, RawRumEvent } from '../../rawRumEvent.types'
67
import { RumEventType } from '../../rawRumEvent.types'
@@ -119,11 +120,12 @@ describe('error collection', () => {
119120
expect(error.message).toEqual('foo')
120121
expect(error.source).toEqual(ErrorSource.CUSTOM)
121122

122-
expect(error?.causes?.length).toEqual(2)
123-
expect(error?.causes?.[0].message).toEqual('bar')
124-
expect(error?.causes?.[0].source).toEqual(ErrorSource.CUSTOM)
125-
expect(error?.causes?.[1].message).toEqual('biz')
126-
expect(error?.causes?.[1].source).toEqual(ErrorSource.CUSTOM)
123+
const causes = (error?.causes ?? []) as RawFlatErrorCause[]
124+
expect(causes.length).toEqual(2)
125+
expect(causes[0].message).toEqual('bar')
126+
expect(causes[0].source).toEqual(ErrorSource.CUSTOM)
127+
expect(causes[1].message).toEqual('biz')
128+
expect(causes[1].source).toEqual(ErrorSource.CUSTOM)
127129
})
128130

129131
it('should extract fingerprint from error', () => {

0 commit comments

Comments
 (0)