From 59ace19e2ce9966c6c80b85184053a2f684896b6 Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Fri, 28 Feb 2025 17:27:35 +0000 Subject: [PATCH 01/10] Init rule for promise prefer-catch --- crates/oxc_linter/src/rules.rs | 2 + .../src/rules/promise/prefer_catch.rs | 109 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 crates/oxc_linter/src/rules/promise/prefer_catch.rs diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 118cdd62d25ee..2b55b429aa0f2 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -530,6 +530,7 @@ mod promise { pub mod param_names; pub mod prefer_await_to_callbacks; pub mod prefer_await_to_then; + pub mod prefer_catch; pub mod spec_only; pub mod valid_params; } @@ -865,6 +866,7 @@ oxc_macros::declare_all_lint_rules! { promise::no_new_statics, promise::no_return_in_finally, promise::param_names, + promise::prefer_catch, promise::prefer_await_to_callbacks, promise::prefer_await_to_then, promise::spec_only, diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs new file mode 100644 index 0000000000000..6a8dda8239331 --- /dev/null +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -0,0 +1,109 @@ +use oxc_diagnostics::OxcDiagnostic; +use oxc_macros::declare_oxc_lint; +use oxc_span::Span; + +use crate::{ + AstNode, + context::LintContext, + fixer::{RuleFix, RuleFixer}, + rule::Rule, +}; + +fn prefer_catch_diagnostic(span: Span) -> OxcDiagnostic { + // See for details + OxcDiagnostic::warn("Should be an imperative statement about what is wrong") + .with_help("Should be a command-like statement that tells the user how to fix the issue") + .with_label(span) +} + +#[derive(Debug, Default, Clone)] +pub struct PreferCatch; + +declare_oxc_lint!( + /// ### What it does + /// + /// + /// ### Why is this bad? + /// + /// + /// ### Examples + /// + /// Examples of **incorrect** code for this rule: + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// ``` + /// + /// Examples of **correct** code for this rule: + /// ```js + /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// ``` + PreferCatch, + promise, + nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style` + // See for details + + pending // TODO: describe fix capabilities. Remove if no fix can be done, + // keep at 'pending' if you think one could be added but don't know how. + // Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion' +); + +impl Rule for PreferCatch { + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {} +} + +#[test] +fn test() { + use crate::tester::Tester; + + let pass = vec![ + "prom.then()", + "prom.then(fn)", + "prom.then(fn1).then(fn2)", + "prom.then(() => {})", + "prom.then(function () {})", + "prom.catch()", + "prom.catch(handleErr).then(handle)", + "prom.catch(handleErr)", + ]; + + let fail = vec![ + "hey.then(fn1, fn2)", + "hey.then(fn1, (fn2))", + "hey.then(null, fn2)", + "hey.then(undefined, fn2)", + "function foo() { hey.then(x => {}, () => {}) }", + " + function foo() { + hey.then(function a() { }, function b() {}).then(fn1, fn2) + } + ", + ]; + + let fix = vec![ + ("hey.then(fn1, fn2)", "hey.catch(fn2).then(fn1)", None), + ("hey.then(fn1, (fn2))", "hey.catch(fn2).then(fn1)", None), + ("hey.then(null, fn2)", "hey.catch(fn2)", None), + ("hey.then(undefined, fn2)", "hey.catch(fn2)", None), + ( + "function foo() { hey.then(x => {}, () => {}) }", + "function foo() { hey.catch(() => {}).then(x => {}) }", + None, + ), + ( + " + function foo() { + hey.then(function a() { }, function b() {}).then(fn1, fn2) + } + ", + " + function foo() { + hey.catch(function b() {}).then(function a() { }).catch(fn2).then(fn1) + } + ", + None, + ), + ]; + Tester::new(PreferCatch::NAME, PreferCatch::PLUGIN, pass, fail) + .expect_fix(fix) + .test_and_snapshot(); +} From b3732837d71635b12ebd34504ee0af61a40ae25b Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Fri, 28 Feb 2025 22:13:25 +0000 Subject: [PATCH 02/10] wip --- .../src/rules/promise/prefer_catch.rs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 6a8dda8239331..8b9513efeae7e 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -1,3 +1,7 @@ +use oxc_ast::{ + AstKind, + ast::{CallExpression, Expression}, +}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; @@ -48,7 +52,35 @@ declare_oxc_lint!( ); impl Rule for PreferCatch { - fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {} + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + let AstKind::ExpressionStatement(expr) = node.kind() else { + return; + }; + + let Expression::CallExpression(ref call_expr) = expr.expression else { + return; + }; + + let Some(member_expr) = call_expr.callee.get_member_expr() else { + return; + }; + + let is_promise_then_call = member_expr + .static_property_name() + .map_or_else(|| false, |prop_name| matches!(prop_name, "then")); + + if !is_promise_then_call { + println!("_______"); + + println!("not a promise then: {node:?}"); + println!("_______"); + } + // todo is arg count geq to 2? if so then flag violation + + //println!("aa {is_promise_then_call:?}"); + //println!("aa {node:?}"); + //println!("call {call_expr:?}"); + } } #[test] @@ -56,6 +88,11 @@ fn test() { use crate::tester::Tester; let pass = vec![ + // not promise related + "foo()", + "a.foo()", + "var a = new Foo()", + // I added these ^^ "prom.then()", "prom.then(fn)", "prom.then(fn1).then(fn2)", From b3205c54ffca3b49d1d47cc35005d489a4dbda01 Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Sat, 1 Mar 2025 13:03:33 +0000 Subject: [PATCH 03/10] Doc examples --- .../src/rules/promise/prefer_catch.rs | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 8b9513efeae7e..47f158f34341f 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -4,7 +4,7 @@ use oxc_ast::{ }; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; -use oxc_span::Span; +use oxc_span::{GetSpan, Span}; use crate::{ AstNode, @@ -26,20 +26,36 @@ pub struct PreferCatch; declare_oxc_lint!( /// ### What it does /// + /// Disallows passing an argument into the second parameter of `then` calls, favouring the use + /// of `catch` for handling promise errors instead. /// /// ### Why is this bad? /// + /// A then call with two arguments can make it more difficult to recognize that a catch error handler is present. + /// Also, using the second argument in `then` calls makes the ordering of promise error handling les + /// obvious. + /// + /// For example on first glance it may appear that `prom.then(fn1, fn2)` is equivalent to + /// `prom.then(fn1).catch(fn2)`. However they aren't equivalent. In fact + /// `prom.catch(fn2).then(fn1)` is the equivalent. + /// + /// This easy confusion is a good reason for prefering explicit `catch` calls over passing an argument + /// to the second parameter of `then` calls. /// /// ### Examples /// /// Examples of **incorrect** code for this rule: /// ```js - /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// prom.then(fn1, fn2) + /// + /// prom.then(null, fn2) /// ``` /// /// Examples of **correct** code for this rule: /// ```js - /// FIXME: Tests will fail if examples are missing or syntactically incorrect. + /// prom.catch(fn2).then(fn1) + /// + /// prom.catch(fn2) /// ``` PreferCatch, promise, @@ -71,6 +87,9 @@ impl Rule for PreferCatch { if !is_promise_then_call { println!("_______"); + let s = node.span().source_text(ctx.source_text()); + println!("{s:?}"); + println!("not a promise then: {node:?}"); println!("_______"); @@ -92,6 +111,7 @@ fn test() { "foo()", "a.foo()", "var a = new Foo()", + "foo().then()", // I added these ^^ "prom.then()", "prom.then(fn)", @@ -104,37 +124,37 @@ fn test() { ]; let fail = vec![ - "hey.then(fn1, fn2)", - "hey.then(fn1, (fn2))", - "hey.then(null, fn2)", - "hey.then(undefined, fn2)", - "function foo() { hey.then(x => {}, () => {}) }", - " - function foo() { - hey.then(function a() { }, function b() {}).then(fn1, fn2) - } - ", + "prom().then()", + // I added ^ + "prom.then(fn1, fn2)", + "prom.then(fn1, (fn2))", + "prom.then(null, fn2)", + "prom.then(undefined, fn2)", + "function foo() { prom.then(x => {}, () => {}) }", + "function foo() { + prom.then(function a() { }, function b() {}).then(fn1, fn2) + }", ]; let fix = vec![ - ("hey.then(fn1, fn2)", "hey.catch(fn2).then(fn1)", None), - ("hey.then(fn1, (fn2))", "hey.catch(fn2).then(fn1)", None), - ("hey.then(null, fn2)", "hey.catch(fn2)", None), - ("hey.then(undefined, fn2)", "hey.catch(fn2)", None), + ("prom.then(fn1, fn2)", "prom.catch(fn2).then(fn1)", None), + ("prom.then(fn1, (fn2))", "prom.catch(fn2).then(fn1)", None), + ("prom.then(null, fn2)", "prom.catch(fn2)", None), + ("prom.then(undefined, fn2)", "prom.catch(fn2)", None), ( - "function foo() { hey.then(x => {}, () => {}) }", - "function foo() { hey.catch(() => {}).then(x => {}) }", + "function foo() { prom.then(x => {}, () => {}) }", + "function foo() { prom.catch(() => {}).then(x => {}) }", None, ), ( " function foo() { - hey.then(function a() { }, function b() {}).then(fn1, fn2) + prom.then(function a() { }, function b() {}).then(fn1, fn2) } ", " function foo() { - hey.catch(function b() {}).then(function a() { }).catch(fn2).then(fn1) + prom.catch(function b() {}).then(function a() { }).catch(fn2).then(fn1) } ", None, From ccb4c22d59540a2a55aece01b3876614b7cf817b Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Sat, 1 Mar 2025 13:10:25 +0000 Subject: [PATCH 04/10] Doc examples --- crates/oxc_linter/src/rules/promise/prefer_catch.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 47f158f34341f..1681cf9c3b6c4 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -26,14 +26,14 @@ pub struct PreferCatch; declare_oxc_lint!( /// ### What it does /// - /// Disallows passing an argument into the second parameter of `then` calls, favouring the use - /// of `catch` for handling promise errors instead. + /// Prefer `catch` to `then(a, b)` and `then(null, b)`. This rule disallows the passing of an + /// argument into the second parameter of `then` calls for handling promise errors. /// /// ### Why is this bad? /// - /// A then call with two arguments can make it more difficult to recognize that a catch error handler is present. - /// Also, using the second argument in `then` calls makes the ordering of promise error handling les - /// obvious. + /// A `then` call with two arguments can make it more difficult to recognize that a catch error + /// handler is present. Another issue with using the second argument in `then` calls is that + /// the ordering of promise error handling is less obvious. /// /// For example on first glance it may appear that `prom.then(fn1, fn2)` is equivalent to /// `prom.then(fn1).catch(fn2)`. However they aren't equivalent. In fact From 827ab6f8e8164aa2fa4ae88890eb8834290cdd4b Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Sun, 2 Mar 2025 21:56:54 +0000 Subject: [PATCH 05/10] Wip --- .../src/rules/promise/prefer_catch.rs | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 1681cf9c3b6c4..6c6d4cbb80692 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -88,17 +88,23 @@ impl Rule for PreferCatch { if !is_promise_then_call { println!("_______"); let s = node.span().source_text(ctx.source_text()); - println!("{s:?}"); + println!("NOT -> {s:?}"); - println!("not a promise then: {node:?}"); + // println!("not a promise then: {node:?}"); println!("_______"); } - // todo is arg count geq to 2? if so then flag violation - //println!("aa {is_promise_then_call:?}"); - //println!("aa {node:?}"); - //println!("call {call_expr:?}"); + if is_promise_then_call { + let s = node.span().source_text(ctx.source_text()); + println!("IS - > {s:?}"); + + if call_expr.arguments.len() >= 2 { + println!("{0:?}",call_expr.arguments.len() >= 2); +ctx.diagnostic(prefer_catch_diagnostic(call_expr.span)); + } + + } } } @@ -107,12 +113,6 @@ fn test() { use crate::tester::Tester; let pass = vec![ - // not promise related - "foo()", - "a.foo()", - "var a = new Foo()", - "foo().then()", - // I added these ^^ "prom.then()", "prom.then(fn)", "prom.then(fn1).then(fn2)", @@ -124,8 +124,6 @@ fn test() { ]; let fail = vec![ - "prom().then()", - // I added ^ "prom.then(fn1, fn2)", "prom.then(fn1, (fn2))", "prom.then(null, fn2)", @@ -136,6 +134,7 @@ fn test() { }", ]; + /* Todo let fix = vec![ ("prom.then(fn1, fn2)", "prom.catch(fn2).then(fn1)", None), ("prom.then(fn1, (fn2))", "prom.catch(fn2).then(fn1)", None), @@ -147,20 +146,17 @@ fn test() { None, ), ( - " - function foo() { - prom.then(function a() { }, function b() {}).then(fn1, fn2) - } - ", - " - function foo() { - prom.catch(function b() {}).then(function a() { }).catch(fn2).then(fn1) - } - ", + "function foo() { + prom.then(function a() { }, function b() {}).then(fn1, fn2) + }", + "function foo() { + prom.catch(function b() {}).then(function a() { }).catch(fn2).then(fn1) + }", None, ), ]; + */ Tester::new(PreferCatch::NAME, PreferCatch::PLUGIN, pass, fail) - .expect_fix(fix) + // .expect_fix(fix) .test_and_snapshot(); } From 822a56b154f99f9163626a0d9130cc3f5f9231c3 Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Sun, 2 Mar 2025 22:30:38 +0000 Subject: [PATCH 06/10] Finished adding implementation of promise/prefer-catch --- .../src/rules/promise/prefer_catch.rs | 58 +++++-------------- .../src/snapshots/promise_prefer_catch.snap | 46 +++++++++++++++ 2 files changed, 61 insertions(+), 43 deletions(-) create mode 100644 crates/oxc_linter/src/snapshots/promise_prefer_catch.snap diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 6c6d4cbb80692..6a7e2a1fbd155 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -1,22 +1,15 @@ -use oxc_ast::{ - AstKind, - ast::{CallExpression, Expression}, -}; +use oxc_ast::{AstKind, ast::Expression}; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; -use oxc_span::{GetSpan, Span}; +use oxc_span::Span; -use crate::{ - AstNode, - context::LintContext, - fixer::{RuleFix, RuleFixer}, - rule::Rule, -}; +use crate::{AstNode, context::LintContext, rule::Rule}; fn prefer_catch_diagnostic(span: Span) -> OxcDiagnostic { - // See for details - OxcDiagnostic::warn("Should be an imperative statement about what is wrong") - .with_help("Should be a command-like statement that tells the user how to fix the issue") + OxcDiagnostic::warn("Prefer `catch` to `then(a, b)` or `then(null, b)`") + .with_help( + "Handle promise errors in a `catch` instead of using the second argument of `then`.", + ) .with_label(span) } @@ -59,12 +52,8 @@ declare_oxc_lint!( /// ``` PreferCatch, promise, - nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style` - // See for details - - pending // TODO: describe fix capabilities. Remove if no fix can be done, - // keep at 'pending' if you think one could be added but don't know how. - // Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion' + style, + pending ); impl Rule for PreferCatch { @@ -85,25 +74,8 @@ impl Rule for PreferCatch { .static_property_name() .map_or_else(|| false, |prop_name| matches!(prop_name, "then")); - if !is_promise_then_call { - println!("_______"); - let s = node.span().source_text(ctx.source_text()); - println!("NOT -> {s:?}"); - - - // println!("not a promise then: {node:?}"); - println!("_______"); - } - - if is_promise_then_call { - let s = node.span().source_text(ctx.source_text()); - println!("IS - > {s:?}"); - - if call_expr.arguments.len() >= 2 { - println!("{0:?}",call_expr.arguments.len() >= 2); -ctx.diagnostic(prefer_catch_diagnostic(call_expr.span)); - } - + if is_promise_then_call && call_expr.arguments.len() >= 2 { + ctx.diagnostic(prefer_catch_diagnostic(call_expr.span)); } } } @@ -130,11 +102,11 @@ fn test() { "prom.then(undefined, fn2)", "function foo() { prom.then(x => {}, () => {}) }", "function foo() { - prom.then(function a() { }, function b() {}).then(fn1, fn2) - }", + prom.then(function a() { }, function b() {}).then(fn1, fn2) + }", ]; - /* Todo + /* Pending let fix = vec![ ("prom.then(fn1, fn2)", "prom.catch(fn2).then(fn1)", None), ("prom.then(fn1, (fn2))", "prom.catch(fn2).then(fn1)", None), @@ -157,6 +129,6 @@ fn test() { ]; */ Tester::new(PreferCatch::NAME, PreferCatch::PLUGIN, pass, fail) - // .expect_fix(fix) + // .expect_fix(fix) .test_and_snapshot(); } diff --git a/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap new file mode 100644 index 0000000000000..dd0f8b15998b5 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap @@ -0,0 +1,46 @@ +--- +source: crates/oxc_linter/src/tester.rs +--- + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:1:1] + 1 │ prom.then(fn1, fn2) + · ─────────────────── + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:1:1] + 1 │ prom.then(fn1, (fn2)) + · ───────────────────── + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:1:1] + 1 │ prom.then(null, fn2) + · ──────────────────── + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:1:1] + 1 │ prom.then(undefined, fn2) + · ───────────────────────── + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:1:18] + 1 │ function foo() { prom.then(x => {}, () => {}) } + · ──────────────────────────── + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + + ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` + ╭─[prefer_catch.tsx:2:9] + 1 │ function foo() { + 2 │ prom.then(function a() { }, function b() {}).then(fn1, fn2) + · ─────────────────────────────────────────────────────────── + 3 │ } + ╰──── + help: Handle promise errors in a `.catch` instead of using the second argument of `then`. From c7dcfe346e6af1daa3b7ca387b56593798f657e4 Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Sun, 2 Mar 2025 22:33:55 +0000 Subject: [PATCH 07/10] Fix typo --- crates/oxc_linter/src/rules/promise/prefer_catch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index 6a7e2a1fbd155..be0948ade36a9 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -32,7 +32,7 @@ declare_oxc_lint!( /// `prom.then(fn1).catch(fn2)`. However they aren't equivalent. In fact /// `prom.catch(fn2).then(fn1)` is the equivalent. /// - /// This easy confusion is a good reason for prefering explicit `catch` calls over passing an argument + /// This easy confusion is a good reason for preferring explicit `catch` calls over passing an argument /// to the second parameter of `then` calls. /// /// ### Examples From 19ea93eed35663dfc750e854b03beaa1c6b8c4ed Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Mon, 3 Mar 2025 09:38:01 +0000 Subject: [PATCH 08/10] Update snapshot --- .../src/snapshots/promise_prefer_catch.snap | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap index dd0f8b15998b5..283dbb4385b7c 100644 --- a/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap +++ b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap @@ -6,35 +6,35 @@ source: crates/oxc_linter/src/tester.rs 1 │ prom.then(fn1, fn2) · ─────────────────── ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` ╭─[prefer_catch.tsx:1:1] 1 │ prom.then(fn1, (fn2)) · ───────────────────── ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` ╭─[prefer_catch.tsx:1:1] 1 │ prom.then(null, fn2) · ──────────────────── ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` ╭─[prefer_catch.tsx:1:1] 1 │ prom.then(undefined, fn2) · ───────────────────────── ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` ╭─[prefer_catch.tsx:1:18] 1 │ function foo() { prom.then(x => {}, () => {}) } · ──────────────────────────── ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` ╭─[prefer_catch.tsx:2:9] @@ -43,4 +43,4 @@ source: crates/oxc_linter/src/tester.rs · ─────────────────────────────────────────────────────────── 3 │ } ╰──── - help: Handle promise errors in a `.catch` instead of using the second argument of `then`. + help: Handle promise errors in a `catch` instead of using the second argument of `then`. From 495d352370b3cbc8994e1fd4289f22f094377d87 Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Mon, 3 Mar 2025 09:41:35 +0000 Subject: [PATCH 09/10] Update doc wording --- crates/oxc_linter/src/rules/promise/prefer_catch.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/oxc_linter/src/rules/promise/prefer_catch.rs b/crates/oxc_linter/src/rules/promise/prefer_catch.rs index be0948ade36a9..19e3e92c670d5 100644 --- a/crates/oxc_linter/src/rules/promise/prefer_catch.rs +++ b/crates/oxc_linter/src/rules/promise/prefer_catch.rs @@ -30,10 +30,9 @@ declare_oxc_lint!( /// /// For example on first glance it may appear that `prom.then(fn1, fn2)` is equivalent to /// `prom.then(fn1).catch(fn2)`. However they aren't equivalent. In fact - /// `prom.catch(fn2).then(fn1)` is the equivalent. - /// - /// This easy confusion is a good reason for preferring explicit `catch` calls over passing an argument - /// to the second parameter of `then` calls. + /// `prom.catch(fn2).then(fn1)` is the equivalent. This kind of confusion is a good reason for + /// preferring explicit `catch` calls over passing an argument to the second parameter of + /// `then` calls. /// /// ### Examples /// @@ -102,8 +101,8 @@ fn test() { "prom.then(undefined, fn2)", "function foo() { prom.then(x => {}, () => {}) }", "function foo() { - prom.then(function a() { }, function b() {}).then(fn1, fn2) - }", + prom.then(function a() { }, function b() {}).then(fn1, fn2) + }", ]; /* Pending From a079415cfceb35d1f23dbe3c3fa6b68e2dd6223b Mon Sep 17 00:00:00 2001 From: therewillbecode Date: Mon, 3 Mar 2025 12:22:53 +0000 Subject: [PATCH 10/10] Update snapshot --- crates/oxc_linter/src/snapshots/promise_prefer_catch.snap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap index 283dbb4385b7c..478f2561e94e2 100644 --- a/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap +++ b/crates/oxc_linter/src/snapshots/promise_prefer_catch.snap @@ -37,10 +37,10 @@ source: crates/oxc_linter/src/tester.rs help: Handle promise errors in a `catch` instead of using the second argument of `then`. ⚠ eslint-plugin-promise(prefer-catch): Prefer `catch` to `then(a, b)` or `then(null, b)` - ╭─[prefer_catch.tsx:2:9] + ╭─[prefer_catch.tsx:2:6] 1 │ function foo() { - 2 │ prom.then(function a() { }, function b() {}).then(fn1, fn2) - · ─────────────────────────────────────────────────────────── - 3 │ } + 2 │ prom.then(function a() { }, function b() {}).then(fn1, fn2) + · ─────────────────────────────────────────────────────────── + 3 │ } ╰──── help: Handle promise errors in a `catch` instead of using the second argument of `then`.