fix(linter/eslint/prefer-promise-reject-errors): handle parenthesized calls (#25378)

## Summary

- Recognize parenthesized rest-parameter reject calls such as `(rest[1])(5)`.
- Reuse `outermost_paren_parent` so the rule skips only parenthesis wrappers before identifying the call.
This commit is contained in:
camc314 committed 2026-08-09 12:51:54 +00:00
1 parent 281124b43b
commit 675c840319
2 files changed
+23 -4

No files matched your search

@@ -12,7 +12,7 @@ use serde_json::Value;
use crate::{
AstNode,
ast_util::{could_be_error, is_method_call},
ast_util::{could_be_error, is_method_call, outermost_paren_parent},
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
@@ -194,7 +194,11 @@ fn check_reject_in_function(
continue;
}
if let AstKind::CallExpression(call_expr) = ctx.nodes().parent_kind(parent.id()) {
let Some(parent) = outermost_paren_parent(parent, ctx) else { continue };
if let AstKind::CallExpression(call_expr) = parent.kind()
&& call_expr.callee.span().contains_inclusive(member_expr.span)
{
check_reject_call(call_expr, ctx, allow_empty_reject);
}
}
@@ -254,10 +258,9 @@ fn test() {
("new Promise(function (resolve, ...rest) { rest[0](new Error('')); });", None),
("new Promise(function (...rest) { rest[0](new Error('')); });", None),
("new Promise(function (...rest) { rest[1](new Error('')); });", None),
("new Promise(function (...rest) { foo(5, (rest[1])); });", None),
// This is fundamentally false, but we can not recognize the value of `i`.
("new Promise(function (resolve, ...rest) { rest[i](5); });", None),
// TODO: This currently passes, as we only look at the immediate parent of the member expression
("new Promise(function (...rest) { (rest[1])(5); });", None),
];
let fail = vec![
@@ -318,6 +321,8 @@ fn test() {
("Promise.reject(foo &&= 5)", None),
("new Promise(function (resolve, ...rest) { rest[0](5); });", None),
("new Promise(function (...rest) { rest[1](5); });", None),
("new Promise(function (...rest) { (rest[1])(5); });", None),
("new Promise(function (...rest) { ((rest[1]))(5); });", None),
];
Tester::new(PreferPromiseRejectErrors::NAME, PreferPromiseRejectErrors::PLUGIN, pass, fail)
@@ -290,3 +290,17 @@ source: crates/oxc_linter/src/tester.rs
· ──────────
╰────
help: Only pass an Error object to the reject() function for user-defined errors in Promises.
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
╭─[prefer_promise_reject_errors.tsx:1:34]
1 │ new Promise(function (...rest) { (rest[1])(5); });
· ────────────
╰────
help: Only pass an Error object to the reject() function for user-defined errors in Promises.
⚠ eslint(prefer-promise-reject-errors): Expected the Promise rejection reason to be an Error
╭─[prefer_promise_reject_errors.tsx:1:34]
1 │ new Promise(function (...rest) { ((rest[1]))(5); });
· ──────────────
╰────
help: Only pass an Error object to the reject() function for user-defined errors in Promises.