feat(linter/unicorn): implement no-useless-error-capture-stack-trace#14222
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
CodSpeed Instrumentation Performance ReportMerging #14222 will not alter performanceComparing Summary
Footnotes
|
9fc9b52 to
92406f0
Compare
4f48cf4 to
5bf292b
Compare
92406f0 to
588ada4
Compare
588ada4 to
990b737
Compare
990b737 to
f1fc264
Compare
5bf292b to
4c3f1ac
Compare
f1fc264 to
7449b74
Compare
7449b74 to
dbbe1a0
Compare
dbbe1a0 to
022402f
Compare
There was a problem hiding this comment.
Pull Request Overview
Adds support for the no-useless-error-capture-stack-trace rule from eslint-plugin-unicorn, which detects unnecessary calls to Error.captureStackTrace() inside constructors of Error subclasses.
- Implements rule logic to detect
Error.captureStackTrace()calls within Error subclass constructors - Adds comprehensive test cases covering various scenarios including arrow functions and static blocks
- Updates rule count in snapshot files across the codebase
Reviewed Changes
Copilot reviewed 48 out of 49 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| crates/oxc_linter/src/rules/unicorn/no_useless_error_capture_stack_trace.rs | Main rule implementation with AST traversal and Error subclass detection |
| crates/oxc_linter/src/snapshots/unicorn_no_useless_error_capture_stack_trace.snap | Test output snapshots showing diagnostic messages |
| crates/oxc_linter/src/rules.rs | Rule registration and module declaration |
| apps/oxlint/src/snapshots/*.snap | Updated rule count from 89/90/91 to 90/91/92 reflecting new rule addition |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
@Sysix or @camchenry do you mind giving this a quick review, and a sanity check that this should be a correctness rule? Thanks |
022402f to
442783d
Compare
442783d to
95ac310
Compare
96c4d77 to
0a9074f
Compare
0a9074f to
eb6345f
Compare
95ac310 to
38f9b9d
Compare
38f9b9d to
264d02e
Compare
Sysix
left a comment
There was a problem hiding this comment.
The main use case for Error.captureStackTrace() is to install a stack trace on a custom error object. Typically, you define custom errors by extending the Error class, which automatically makes the stack property available via inheritance. However, the problem with the default stack trace is that it includes the constructor call itself, which leaks implementation details. You can avoid this by using Error.captureStackTrace(), which allows the stack trace to be installed even for custom errors that do not inherit from Error.
class MyError extends Error {
constructor(message, options) {
super(message, options);
}
}
const myError = new MyError("Something went wrong");
console.log(myError.stack);
// output:
MyError@debugger eval code:3:5
@debugger eval code:7:17
class MyError extends Error {
constructor(message, options) {
super(message, options);
if ("captureStackTrace" in Error) {
// Avoid MyError itself in the stack trace
Error.captureStackTrace(this, MyError);
}
}
}
const myError = new MyError("Something went wrong");
console.log(myError.stack);
// output:
@debugger eval code:11:17
Reading the docs, this should not be correctness, because it could want to ignore it stack trace output for MyError.
Maybe Restriction or Suspicious ? :)
|
hmm let me test this later. unicorn refers to the call as useless, which to me implies correctness. i wonder if calling super before captureStackYrace is correct, but if you skip super it isn't? thanks for looking |
264d02e to
23aadd0
Compare
Merge activity
|
23aadd0 to
3d5db4a
Compare
## [1.20.0] - 2025-10-06 ### 🚀 Features - d16df93 linter: Support disable directives for type aware rules (#14052) (camc314) - f5c6acc linter: Add `vue/no-export-in-script-setup` rule (#14307) (Sysix) - 353b153 linter: Implement eslint/no-param-reassign rule (#14341) (Matthew Davis) - a2914fe linter/plugins: Add `loc` field getter to all AST nodes (#14355) (overlookmotel) - 07193c2 linter/plugins: Implement `SourceCode#getAncestors` (#14346) (overlookmotel) - c8de6fe linter/plugins: Add `parent` field to AST nodes (#14345) (overlookmotel) - 5505a86 linter/plugins: Include `range` field in AST (#14321) (overlookmotel) - 3656908 rust: Oxc-index-vec v4.0 (#14254) (Boshen) - 1347de4 linter/plugins: Accept diagnostics with `loc` (#14304) (overlookmotel) - aefc8b3 linter/plugins: Implement `SourceCode#getIndexFromLoc` and `getLocFromIndex` (#14303) (overlookmotel) - 93807db linter/plugins: Implement `SourceCode#lines` property (#14290) (overlookmotel) - 2f8c985 linter/plugins: Implement `SourceCode#visitorKeys` property (#14289) (overlookmotel) - b69028f linter/plugins: Implement `SourceCode#ast` property (#14287) (overlookmotel) - d8d3d18 linter: Add `vue/prefer-import-from-vue` rule (#14284) (Sysix) - f0e760b linter: Add `vue/define-props-destructuring` rule (#14272) (Sysix) - bdf9010 linter/plugins: Add `SourceCode` API (#14281) (overlookmotel) - 7f450fc linter/unicorn: Implement require-module-specifiers (#13089) (keita hino) - a1e7154 linter/unicorn: Implement prefer-classlist-toggle (#14262) (camc314) - 8217dce linter/unicorn: Implement no-unnecessary-array-splice-count (#14255) (camc314) - 3d5db4a linter/unicorn: Implement no-useless-error-capture-stack-trace (#14222) (camc314) - b3b482a linter/unicorn: Implement prefer-top-level-await (#14247) (camc314) - 7931be8 linter/unicorn: Implement prefer-class-fields (#14245) (camc314) - a39434a linter/unicorn: Implement prefer-at (#14232) (camc314) ### 🐛 Bug Fixes - e605222 linter/no-useless-undefined: Correctly respect `checkArguments` option (#14369) (camc314) - f1bc608 linter: Fix flaky import/no_cycle test (#14328) (Boshen) - 9a902c0 linter/plugins: Make `range` field non-optional on AST types (#14354) (overlookmotel) - 0a42d7f tsgolint: Report errors if we fail to parse tsgolint diagnostic messages (#14301) (camc314) - 42f8d7e linter/react-hooks: Fix diagnostic message for literal in dependency array (#14266) (camc314) - ece91c5 linter/react-hooks: Fix diagnostic message for duplicate dependency in array (#14265) (camc314) - 864fa0e linter/no-unused-expression: False positive with satisfies expressions (#14259) (camc314) - adff069 language_server: Don't apply "ignore this rule" fixes for fixAll code action + command (#14243) (Sysix) - 46cceb8 linter/rules-of-hooks: Correctly place primary span to fix disable directive (#14237) (camc314) ### 🚜 Refactor - 1489376 napi/parser, linter/plugins: Minify walker code (#14376) (overlookmotel) - c8eeeb5 linter/plugins: Remove build-time dependency on `napi/parser` (#14374) (overlookmotel) - fb1a067 linter/plugins: Bundle walker and AST types map (#14373) (overlookmotel) - 93d8164 linter/plugins: Export AST types direct from `oxlint` package (#14353) (overlookmotel) - 230d996 linter/plugins: `SourceCode#getText` use `range` (#14352) (overlookmotel) - 6e52bbd linter/plugins: Move location-related code into separate file (#14350) (overlookmotel) - 13f1003 linter/plugins: Share `ast` between files (#14349) (overlookmotel) - 00dde41 tsgolint: Make parsing `TsGoLintMessage` parsing errors an enum (#14300) (camc314) - fc314f5 tsgolint: Make `MessageType` parsing more idomatic (#14299) (camc314) - a24c36e language-server/tsgolint: Use an iterator for tsgolint message parsing (#14298) (camc314) - 8be432a tsgolint: Use an iterator for tsgolint message parsing (#14297) (camc314) - 57daa54 tsgolint: Remove always `Some` option wrapper (#14296) (camc314) - 79eadf8 linter: Introduce `LintRunner` (#14051) (camc314) - 65873ba linter/plugins: Add stubs for all `SourceCode` methods (#14285) (overlookmotel) - 989ce2f linter/plugins: Convert `Node` type to interface (#14280) (overlookmotel) - 891fc47 language_server: Share code for command `oxc.fixAll` and code action `source.fixAll.oxc` (#14244) (Sysix) - 7fe930c language_server: Remove unused fixture files (#14246) (Sysix) - 2b2c345 language-server: Move `generate_inverted_diagnostics` to `error_with_position` (#14118) (camc314) ### ⚡ Performance - fa3712d language_server: Create less `ExternalPluginStore`s (#14378) (overlookmotel) - e75d42d napi/parser, linter/plugins: Remove runtime `preserveParens` option from raw transfer deserializers (#14338) (overlookmotel) - 2e57351 linter/plugins: Initialize `lineStartOffsets` as `[0]` (#14302) (overlookmotel) - c27a393 linter/plugins: Deserialize AST on demand (#14288) (overlookmotel) - 95a8cc4 linter/plugins: Use singleton for `SourceCode` (#14286) (overlookmotel) ### 🧪 Testing - 0061ce7 linter: Add more tests for disable directives in partial loadable files (#14371) (camc314) - 1387aaa linter/plugins: Test `createOnce` returning no visitor functions (#14279) (overlookmotel) - 55ebb8b linter: Add test for `disable_for_this_section` fix (#14240) (Sysix) - a7e8662 linter: Port unicorn test cases to no-named-default (#14239) (camc314) Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>

No description provided.