Skip to content

Commit c72bf05

Browse files
authored
test(core): Keeping mechanism on captured error, not on its chained cause (#23244)
1 parent 8768c38 commit c72bf05

3 files changed

Lines changed: 105 additions & 1 deletion

File tree

dev-packages/browser-integration-tests/suites/public-api/captureException/aggregateError-custom/subject.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,16 @@ const aggregateError = new CustomAggregateError(
1313
},
1414
);
1515

16-
Sentry.captureException(aggregateError);
16+
const shouldUseCustomMechanism = window.location.hash === '#custom-mechanism';
17+
18+
if (shouldUseCustomMechanism) {
19+
const cause = new Error('Failure 1');
20+
const errorCause = new Error('Failure 2', { cause });
21+
const error = new Error('Failure 3', { cause: errorCause });
22+
23+
Sentry.captureException(error, {
24+
mechanism: { handled: false, type: 'auto.http.example' },
25+
});
26+
} else {
27+
Sentry.captureException(aggregateError);
28+
}

dev-packages/browser-integration-tests/suites/public-api/captureException/aggregateError-custom/test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,45 @@ sentryTest('captures custom AggregateErrors', async ({ getLocalTestUrl, page })
3838
}),
3939
]);
4040
});
41+
42+
// fixme: the mechanism should be on the error
43+
sentryTest(
44+
'keeps a custom capture mechanism on the captured error instead of its causes',
45+
async ({ getLocalTestUrl, page }) => {
46+
const url = await getLocalTestUrl({ testDir: __dirname });
47+
const req = await waitForErrorRequestOnUrl(page, `${url}#custom-mechanism`);
48+
const eventData = envelopeRequestParser(req);
49+
50+
expect(eventData.exception?.values).toHaveLength(3);
51+
expect(eventData.exception?.values).toEqual([
52+
expect.objectContaining({
53+
value: 'Failure 1',
54+
mechanism: {
55+
exception_id: 2,
56+
handled: false, // true,
57+
parent_id: 1,
58+
source: 'cause',
59+
type: 'auto.http.example', // 'chained',
60+
},
61+
}),
62+
expect.objectContaining({
63+
value: 'Failure 2',
64+
mechanism: {
65+
exception_id: 1,
66+
handled: true,
67+
parent_id: 0,
68+
source: 'cause',
69+
type: 'chained',
70+
},
71+
}),
72+
expect.objectContaining({
73+
value: 'Failure 3',
74+
mechanism: {
75+
exception_id: 0,
76+
handled: true, // false,
77+
type: 'generic', // 'auto.http.example',
78+
},
79+
}),
80+
]);
81+
},
82+
);

packages/core/test/lib/utils/aggregate-errors.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { Event, EventHint } from '../../../src/types/event';
55
import type { Exception } from '../../../src/types/exception';
66
import type { StackParser } from '../../../src/types/stacktrace';
77
import { applyAggregateErrorsToEvent } from '../../../src/utils/aggregate-errors';
8+
import { addExceptionMechanism } from '../../../src/utils/misc';
89
import { createStackParser } from '../../../src/utils/stacktrace';
910

1011
const stackParser = createStackParser([0, line => ({ filename: line })]);
@@ -116,6 +117,55 @@ describe('applyAggregateErrorsToEvent()', () => {
116117
});
117118
});
118119

120+
// fixme: the mechanism should be on the error
121+
test('keeps a capture mechanism on the captured error instead of its causes', () => {
122+
const cause = new Error('Failure 1');
123+
const errorCause = new Error('Failure 2', { cause });
124+
const error = new Error('Failure 3', { cause: errorCause });
125+
const event: Event = { exception: { values: [exceptionFromError(stackParser, error)] } };
126+
const eventHint: EventHint = {
127+
originalException: error,
128+
mechanism: { handled: false, type: 'auto.http.example' },
129+
};
130+
131+
applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
132+
addExceptionMechanism(event, eventHint.mechanism);
133+
134+
expect(event.exception?.values).toStrictEqual([
135+
{
136+
type: 'Error',
137+
value: 'Failure 1',
138+
mechanism: {
139+
exception_id: 2,
140+
handled: false, // true,
141+
parent_id: 1,
142+
source: 'cause',
143+
type: 'auto.http.example', // 'chained',
144+
},
145+
},
146+
{
147+
type: 'Error',
148+
value: 'Failure 2',
149+
mechanism: {
150+
exception_id: 1,
151+
handled: true,
152+
parent_id: 0,
153+
source: 'cause',
154+
type: 'chained',
155+
},
156+
},
157+
{
158+
type: 'Error',
159+
value: 'Failure 3',
160+
mechanism: {
161+
exception_id: 0,
162+
handled: true, //false,
163+
type: 'instrument', //'auto.http.example',
164+
},
165+
},
166+
]);
167+
});
168+
119169
test('recursively walks errors created in another realm', () => {
120170
const originalException = runInNewContext(
121171
`new AggregateError([new Error('Aggregate child')], 'Root Error', { cause: new Error('Cause') })`,

0 commit comments

Comments
 (0)