+
Skip to content

Conversation

qraqras
Copy link
Contributor

@qraqras qraqras commented Aug 24, 2025

This is my first contribution to the project. I welcome any feedback!

Summary

Closes #6476
Added the new rule noUselessCatchBinding. This rule disallows unnecessary catch bindings.

try {
    // Do something
- } catch (unused) {}
+ } catch {}

Test Plan

Added snap tests.

Docs

Used inline rustdoc only.

Copy link

changeset-bot bot commented Aug 24, 2025

🦋 Changeset detected

Latest commit: 2c5fe9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@biomejs/biome Minor
@biomejs/plugin-api Major
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

coderabbitai bot commented Aug 24, 2025

Walkthrough

Adds a new nursery lint rule NoUselessCatchBinding (crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs) that detects unused catch bindings and provides an unsafe autofix to remove the binding (transforming catch (e) {}catch {}). Adds NoUselessCatchBindingOptions (crates/biome_rule_options/src/no_useless_catch_binding.rs) and re-exports it (crates/biome_rule_options/src/lib.rs). Adds JS/TS test fixtures (valid/invalid) covering identifier and destructuring forms and a changeset entry for the new rule. No existing public APIs were removed.

Assessment against linked issues

Objective Addressed Explanation
Suggest unsafe fix in correctness/noUnusedVariables to remove unused catch binding (#6476) PR implements a separate nursery rule (noUselessCatchBinding) instead of adding the unsafe fix to the existing correctness/noUnusedVariables rule.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Add new nursery rule implementation (crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs) Implements a new separate rule rather than modifying the existing correctness/noUnusedVariables rule requested in the issue.
Add changelog/changeset entry (.changeset/pink-coats-jog.md) Adds release metadata for the new nursery rule; not part of the issue objective to update the existing rule.
Export new rule options and add options type (crates/biome_rule_options/src/lib.rs and crates/biome_rule_options/src/no_useless_catch_binding.rs) Introduces a new options type and public export for the new rule instead of altering options for noUnusedVariables as requested.

Suggested reviewers

  • dyc3
  • ematipico
  • siketyan

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1b8ce65 and 98dc2ae.

⛔ Files ignored due to path filters (2)
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (1)
  • .changeset/pink-coats-jog.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .changeset/pink-coats-jog.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (26)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Documentation
  • GitHub Check: Check JS Files
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_js_parser)
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Aug 24, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js (1)

1-5: Broaden invalid coverage: underscore alias and destructuring.

Two common patterns worth checking:

  • An “intentionally unused” underscore name still unused → should be reported.
  • Destructured catch binding where no bound names are used → should be reported.

Proposed additions:

 try {
     // Do something
 } catch (unused) {
     // Do something
 }
+
+// underscore-named binding is still unused and should be reported
+try {
+    // Do something
+} catch (_e) {
+    // Do something
+}
+
+// destructured catch binding with unused property should be reported
+try {
+    // Do something
+} catch ({ message }) {
+    // Do something
+}
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts (1)

1-5: Mirror JS invalid edge cases in TS.

Parity helps: underscore alias and unused destructuring.

Proposed additions:

 try {
     // Do something
 } catch (unused) {
     // Do something
 }
+
+// underscore-named binding is still unused and should be reported
+try {
+    // Do something
+} catch (_e) {
+    // Do something
+}
+
+// destructured catch binding with unused property should be reported
+try {
+    // Do something
+} catch ({ message }) {
+    // Do something
+}
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1)

1-13: Add positive cases: used destructuring and nested closure capture.

These ensure the rule respects real usage patterns (binding pattern usage; reference captured in closures).

Proposed additions:

 try {
     // Do something
 } catch {
     // Do something
 }
+
+// destructured catch binding with used property should be valid
+try {
+    // Do something
+} catch ({ message }) {
+    console.error(message);
+}
+
+// capturing inside a nested closure should count as usage
+try {
+    // Do something
+} catch (e) {
+    queueMicrotask(() => console.error(e));
+}
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1)

9-13: Add two “no diagnostic” tests: closure-use and destructuring

I searched the test specs and couldn't find a destructured catch or a case where the catch binding is only used inside a nested closure. Please add these to strengthen the rule.

Files to update:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (and mirror to valid.ts if needed)

Suggested snippets to add:

try {
// Do something
} catch (err) {
const log = () => console.error(err);
log();
}

try {
// Do something
} catch ({ message }) {
console.log(message);
}

crates/biome_rule_options/src/no_useless_catch_binding.rs (1)

3-6: Tiny polish: document the options type

A brief doc comment helps downstream config generators and schema users.

Apply this diff:

 #[derive(Default, Clone, Debug, Deserialize, Deserializable, Eq, PartialEq, Serialize)]
 #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
 #[serde(rename_all = "camelCase", deny_unknown_fields, default)]
-pub struct NoUselessCatchBindingOptions {}
+/// Options for the `noUselessCatchBinding` rule.
+/// Currently empty; reserved for future extensions (e.g. allowlist of names).
+pub struct NoUselessCatchBindingOptions {}
crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (2)

60-64: Remove unnecessary clone

catch_binding_ident isn’t reused; the clone is redundant.

Apply this diff:

-        let catch_binding_any_ident = AnyJsIdentifierBinding::from(catch_binding_ident.clone());
+        let catch_binding_any_ident = AnyJsIdentifierBinding::from(catch_binding_ident);

10-41: Docs: reference the standard, not the proposal URL

Optional catch binding shipped in ES2019; linking to the proposal can age poorly. Suggest pointing to the ES2019 feature in the docstring.

Apply this diff:

-    /// This rule enforces removing unnecessary catch bindings in accordance with ECMAScript 2019.
-    /// See also: [Optional catch binding](https://tc39.es/proposal-optional-catch-binding)
+    /// This rule enforces removing unnecessary catch bindings in accordance with ECMAScript 2019.
+    /// See also: the ECMAScript 2019 “optional catch binding” feature in the language specification.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2af2380 and a3a8835.

⛔ Files ignored due to path filters (9)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (8)
  • .changeset/pink-coats-jog.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1 hunks)
  • crates/biome_rule_options/src/lib.rs (1 hunks)
  • crates/biome_rule_options/src/no_useless_catch_binding.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_rule_options/src/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: Create changesets with just new-changeset; store them in .changeset/ with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.

Files:

  • .changeset/pink-coats-jog.md
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/no_useless_catch_binding.rs
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When banning globals (e.g., `console.log`), consult the semantic model to avoid false positives on locally shadowed identifiers

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/{invalid*,valid*}.{js,jsx,ts,tsx,css,graphql,jsonc} : Place snapshot test cases under `tests/specs/<group>/<ruleName>/` using files prefixed with `invalid` and `valid`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_rule_options/src/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule provides a code action, add `fix_kind` in `declare_lint_rule!` and use `ctx.action_category(ctx.category(), ctx.group())` and `ctx.metadata().applicability()` when constructing actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
🔇 Additional comments (4)
crates/biome_rule_options/src/lib.rs (1)

208-210: LGTM: placement alongside no_useless_catch is sensible.

Export order/readability remain consistent with neighbouring modules.

crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1)

3-7: LGTM: positive control where the binding is used

This is a good “no diagnostic” case covering a direct reference inside the catch block.

crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (2)

86-96: Verify trivia/comment preservation in the fix

Removing the entire JsCatchDeclaration will drop any inline comments around the parameter. That’s acceptable for an unsafe fix, but let’s lock behaviour with a snapshot.

Add an invalid test like:

try {} catch (/*leading*/ unused /*trailing*/) {}

and ensure the fixed output is either:

  • catch {} (comments dropped), or
  • /*leading*//*trailing*/ catch {} (comments preserved),
    consistently across JS/TS.

57-68: Handle destructured catch bindings too
The noUselessCatchBinding rule currently only flags simple identifier bindings and will silently skip any destructured parameters (e.g. catch ({ message }) {}). I checked the spec files under
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding and found no tests for destructured catch bindings, so this gap isn’t covered yet.

• The code bails out at as_js_identifier_binding(), ignoring patterns.
• We should collect every AnyJsIdentifierBinding within a destructured pattern and only signal when all are unused.

Shall I draft a patch to:

  1. Extract all identifiers from a binding pattern, and
  2. Signal only if each one is unused?

pub mod no_unused_variables;
pub mod no_unwanted_polyfillio;
pub mod no_useless_catch;
pub mod no_useless_catch_binding;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Generated file warning: ensure codegen picks this up.

This file is marked “Generated file, do not edit by hand”. Please confirm xtask/codegen is updated so this export persists after regeneration.

Run:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# 1) Ensure the options module file exists
fd -a 'no_useless_catch_binding.rs' crates
# 2) Check codegen mentions this module (paths may vary: xtask or crates/xtask)
rg -n -C2 'no_useless_catch_binding' xtask crates/xtask || true

Length of output: 343


Include new catch-binding option in codegen (xtask)

The no_useless_catch_binding.rs file is present and you’ve added:

// crates/biome_rule_options/src/lib.rs:209
pub mod no_useless_catch_binding;

However, our xtask codegen doesn’t mention no_useless_catch_binding, so regenerating will drop this export. Please update your codegen script (likely under xtask/src/ or similar) to include "no_useless_catch_binding". Without this, you’ll need to re-add the export after each regen.

🤖 Prompt for AI Agents
crates/biome_rule_options/src/lib.rs around line 209: the new module
`no_useless_catch_binding` was added but the xtask codegen doesn’t include it,
so regenerating will remove the export; update the xtask codegen (e.g., the
generation list in xtask/src/ or wherever rule option names are enumerated) to
add "no_useless_catch_binding" to the array/list/map of modules it emits, then
re-run the xtask codegen so the export remains persistent after regeneration.

@ematipico
Copy link
Member

The nitpick comments of the code rabbit bot are valid, we should add more tests

Copy link

codspeed-hq bot commented Aug 24, 2025

CodSpeed Performance Report

Merging #7311 will not alter performance

Comparing qraqras:main (2c5fe9a) with main (963a246)

Summary

✅ 133 untouched benchmarks

@qraqras qraqras changed the title feat(biome_js_analyze): add noUselessCatchBindings feat(biome_js_analyze): add noUselessCatchBinding Aug 24, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts (1)

1-1: Fix file header: this is an invalid fixture

Invalid fixtures should declare that they generate diagnostics.

-// should not generate diagnostics
+// should generate diagnostics
🧹 Nitpick comments (5)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1)

3-17: Add a few more “valid” edge cases (alias, nested, rest)

These help guard against false positives with more complex patterns.

Add at the end of the file:

+try { /* ... */ } catch ({ used: alias }: any) { console.error(alias); }
+try { /* ... */ } catch ({ nested: { used } }: any) { console.error(used); }
+try { /* ... */ } catch ({ ...rest }: any) { console.error(rest); }
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1)

3-17: Mirror a couple more “valid” JS cases (alias, nested, rest)

Parities the TS suggestions to future-proof the rule.

Append:

+try { /* ... */ } catch ({ used: alias }) { console.error(alias); }
+try { /* ... */ } catch ({ nested: { used } }) { console.error(used); }
+try { /* ... */ } catch ({ ...rest }) { console.error(rest); }
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts (1)

3-21: Add a couple more invalid TS patterns (rest, nested alias)

Strengthens coverage for patterns that can still be entirely unused.

Consider adding:

+try { /* ... */ } catch ({ ...rest }: any) { }
+try { /* ... */ } catch ({ nested: { unused } }: any) { }
+try { /* ... */ } catch ({ used: _unused }: any) { }
crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (2)

92-101: Minor: avoid allocation when checking bindings

You can stream the descendants and early-return; no need to collect into a Vec.

-        let mut idents: Vec<AnyJsIdentifierBinding> = Vec::new();
-        for descendant in catch_binding.syntax().descendants() {
-            if let Some(ident) = AnyJsIdentifierBinding::cast(descendant) {
-                idents.push(ident);
-            }
-        }
-        if idents.iter().all(|ident| is_unused(model, ident)) {
+        let all_unused = catch_binding
+            .syntax()
+            .descendants()
+            .filter_map(AnyJsIdentifierBinding::cast)
+            .all(|ident| is_unused(model, &ident));
+        if all_unused {
             return Some(());
         }

104-118: Diagnostic copy is clear; consider a short suggestion hint

Optional: a one-liner hint helps users understand the next step without opening the action panel.

             RuleDiagnostic::new(
                 rule_category!(),
                 catch_declaration.range(),
                 markup! {
-                    "This "<Emphasis>"catch binding"</Emphasis>" is unused."
+                    "This "<Emphasis>"catch binding"</Emphasis>" is unused; prefer "<Emphasis>"catch { }"</Emphasis>"."
                 },
             )
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a3a8835 and e7a5cd2.

⛔ Files ignored due to path filters (7)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • .changeset/pink-coats-jog.md (1 hunks)
  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1 hunks)
  • crates/biome_rule_options/src/no_useless_catch_binding.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/biome_rule_options/src/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.js
  • .changeset/pink-coats-jog.md
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule provides a code action, add `fix_kind` in `declare_lint_rule!` and use `ctx.action_category(ctx.category(), ctx.group())` and `ctx.metadata().applicability()` when constructing actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When banning globals (e.g., `console.log`), consult the semantic model to avoid false positives on locally shadowed identifiers

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/{invalid*,valid*}.{js,jsx,ts,tsx,css,graphql,jsonc} : Place snapshot test cases under `tests/specs/<group>/<ruleName>/` using files prefixed with `invalid` and `valid`

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Mark code blocks in docs with a language and required properties: use `expect_diagnostic` for invalid examples (exactly one diagnostic), `options`/`full_options` for config blocks, and `use_options` for subsequent examples

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/invalid.ts
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js
🧬 Code graph analysis (1)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (3)
  • log (10-10)
  • log (12-12)
  • log (14-14)
🔇 Additional comments (3)
crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.ts (1)

3-17: LGTM on the happy-path fixtures

Covers identifier, object patterns, mixed used/unused, and closure captures. Nicely representative.

crates/biome_js_analyze/tests/specs/nursery/noUselessCatchBinding/valid.js (1)

3-17: Solid coverage; mirrors TS cases neatly

No diagnostics expected; the closure-capture scenarios are a nice touch.

crates/biome_js_analyze/src/lint/nursery/no_useless_catch_binding.rs (1)

120-148: Follow-up: add fixer-focused snapshots for comment preservation

You already test a variety of comment placements in invalid.ts. Please add fixer snapshots to assert that “trailing outer” comments are preserved and nothing egregious happens to spacing when no trivia exists. It will keep this fixer from regressing later.

@qraqras qraqras marked this pull request as draft August 25, 2025 13:17
@qraqras qraqras marked this pull request as ready for review August 25, 2025 13:46
@qraqras
Copy link
Contributor Author

qraqras commented Aug 25, 2025

I added tests and updated the logic to ensure they pass.
I also corrected some comments.

@qraqras qraqras requested a review from ematipico August 25, 2025 13:47
@ematipico ematipico merged commit 62154b9 into biomejs:main Sep 2, 2025
31 checks passed
@github-actions github-actions bot mentioned this pull request Sep 4, 2025
dyc3 pushed a commit that referenced this pull request Oct 3, 2025
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 lint/correctness/noUnusedVariables for catch clause should suggest removing variable definition as unsafe fix

2 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载