fix(browser): Add a synthetic stack trace to DOMException with empty stack traces if attachStacktrace is true#19988
Conversation
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Bug Fixes 🐛
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
f16b753 to
0f76c44
Compare
…stack traces if attachStacktrace is true
8cb32a4 to
c26f7a3
Compare
|
LGTM, thanks! Let's see what the CI robots say :) |
|
Thank you for triggering the CI! The current failures appear to be unrelated to the changes in this PR. |
30ba39c to
83ae1e5
Compare
There was a problem hiding this comment.
Thanks for the PR!
I think this is a good change in general but if the test fails then we should ensure the exception report doesn't change. Let's see.
EDIT: Yep it fails, so I think the change will affect grouping significantly.
// before
"type": "SyntaxError",
"value": "The string did not match the expected pattern.",
// after
"type": "Error",
"value": "SyntaxError: The string did not match the expected pattern.",
| const domException = exception as DOMException; | ||
|
|
||
| if ('stack' in (exception as Error)) { | ||
| if ((exception as Error).stack) { |
There was a problem hiding this comment.
h: I think this will change how the dom exceptions are classified, I pushed a test to see if it would pass.
There was a problem hiding this comment.
Maybe something like this would keep the best of both worlds here, could you try something like:
// same check as before
if ('stack' in (exception as Error)) {
event = eventFromError(stackParser, exception as Error);
// preserves the classification while adding stacktraces if it exists...
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 {
// existing fallback
}There was a problem hiding this comment.
Thank you for the review. Your approach seems better, so I will update the PR accordingly.
This isn’t directly related to this PR, but I noticed that while the cases where the stack property is missing and where it’s an empty string are similar, the fact that whether they’re grouped under Error depends on this difference feels inconsistent. I thought it might be more accurate to determine this based on whether the class inherits from Error, as in the original PR #4156, rather than on the presence or absence of the stack property.
There was a problem hiding this comment.
The stack property is not actually a standard, but more like a defacto standard but it is implemented across all browsers which is why it is a bit wonky.
I'm not familiar with the full history of this code path, but my assumption is that we are checking for the capability we need rather than asserting what the object is. In this branch, what matters is whether the exception has a stack property, not necessarily whether it inherits from Error.
Regardless, preserving grouping is important IMO, since changing this classification can affect all users. With this approach, we fix the core issue while preserving the current behavior.
I think this is a good first step. As a follow-up, we can take a closer look at the classification itself, add tests to lock down the behavior we want, and then see whether we can make these checks more semantically consistent.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 901e3ef. Configure here.
logaretm
left a comment
There was a problem hiding this comment.
Looks good now, thanks a lot!
This PR adds the external contributor to the CHANGELOG.md file, so that they are credited for their contribution. See #19988 Co-authored-by: logaretm <[email protected]>

DOMException may not always contain a stack trace. Depending on the browser, the stack property might be missing entirely, or it might be set to an empty string.
This PR ensures that empty strings are handled in the same way as missing properties.
For example, when a NotAllowedError occurs during WebAuthn usage, I confirmed that Chrome does not have the stack property, whereas Safari provides it as an empty string.