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
9 changes: 9 additions & 0 deletions packages/browser/src/eventbuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,15 @@ export function eventFromUnknownInput(

if ('stack' in (exception as Error)) {
event = eventFromError(stackParser, exception as Error);

const firstException = event.exception?.values?.[0];
if (attachStacktrace && syntheticException && firstException && !firstException.stacktrace) {
const frames = parseStackFrames(stackParser, syntheticException);
if (frames.length) {
firstException.stacktrace = { frames };
addExceptionMechanism(event, { synthetic: true });
}
}
} else {
const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');
const message = domException.message ? `${name}: ${domException.message}` : name;
Expand Down
85 changes: 85 additions & 0 deletions packages/browser/test/eventbuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,91 @@ describe('eventFromUnknownInput', () => {
},
});
});

it('add a synthetic stack trace to DOMException with empty stack traces if attachStacktrace is true', async () => {
const exception = new DOMException('The string did not match the expected pattern.', 'SyntaxError');
exception.stack = '';

const syntheticException = new Error('Test message');
const event = await eventFromUnknownInput(defaultStackParser, exception, syntheticException, true);
expect(event.exception?.values?.[0]).toEqual(
expect.objectContaining({
mechanism: { handled: true, synthetic: true, type: 'generic' },
stacktrace: {
frames: expect.arrayContaining([expect.any(Object), expect.any(Object)]),
},
type: 'SyntaxError',
value: 'The string did not match the expected pattern.',
}),
);
});

it('preserves DOMException type when stack is an empty string', () => {
const exception = new DOMException('The string did not match the expected pattern.', 'SyntaxError');
exception.stack = '';

const event = eventFromUnknownInput(defaultStackParser, exception, new Error('synthetic'), true);

expect(event.exception?.values?.[0]).toMatchObject({
type: 'SyntaxError',
value: 'The string did not match the expected pattern.',
});
});
Comment thread
sentry[bot] marked this conversation as resolved.
Comment thread
cursor[bot] marked this conversation as resolved.

it('add a synthetic stack trace to DOMException without a stack traces property if attachStacktrace is true', async () => {
const exception = new DOMException('The string did not match the expected pattern.', 'SyntaxError');
delete exception.stack;

const syntheticException = new Error('Test message');
const event = await eventFromUnknownInput(defaultStackParser, exception, syntheticException, true);
expect(event.exception?.values?.[0]).toEqual(
expect.objectContaining({
mechanism: { handled: true, synthetic: true, type: 'generic' },
stacktrace: {
frames: expect.arrayContaining([expect.any(Object), expect.any(Object)]),
},
type: 'Error',
value: 'SyntaxError: The string did not match the expected pattern.',
}),
);
});

it("doesn't add a synthetic stack trace to DOMException with empty stack traces if attachStacktrace is false", async () => {
const exception = new DOMException('The string did not match the expected pattern.', 'SyntaxError');
exception.stack = '';

const syntheticException = new Error('Test message');
const event = await eventFromUnknownInput(defaultStackParser, exception, syntheticException, false);
expect(event.exception?.values?.[0]).toEqual({
type: 'SyntaxError',
value: 'The string did not match the expected pattern.',
});
});

it("doesn't add a synthetic stack trace to DOMException with stack traces if attachStacktrace is true", async () => {
const exception = new DOMException('The string did not match the expected pattern.', 'SyntaxError');
exception.stack = 'SyntaxError\n at <anonymous>:1:2';

const syntheticException = new Error('Test message');
const event = await eventFromUnknownInput(defaultStackParser, exception, syntheticException, true);
expect(event.exception?.values?.[0]).toEqual(
expect.objectContaining({
stacktrace: {
frames: [
{
colno: 2,
filename: '<anonymous>',
function: '?',
in_app: true,
lineno: 1,
},
],
},
type: 'SyntaxError',
value: 'The string did not match the expected pattern.',
}),
);
});
});

describe('extractMessage', () => {
Expand Down
Loading