feat(linter): implement n/handle-callback-err rule (#19616)

this PR implements `n/handle-callback-err` rule, passes all tests from original [rule](https://github.com/eslint-community/eslint-plugin-n/blob/master/tests/lib/rules/handle-callback-err.js)

issue #493

---------

Signed-off-by: Mikhail Baev <baev2m@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Cameron Clark <cameron.clark@hey.com>
This commit is contained in:
authored and GitHub committed 2026-03-12 16:48:48 +00:00
1 parent 910c941a10
commit 7a2a7d0ab9
5 files changed
+453 -1

No files matched your search

+6
View File
@@ -4310,6 +4310,12 @@ impl RuleRunner for crate::rules::node::global_require::GlobalRequire {
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}
impl RuleRunner for crate::rules::node::handle_callback_err::HandleCallbackErr {
const NODE_TYPES: Option<&AstTypesBitset> =
Some(&AstTypesBitset::from_types(&[AstType::ArrowFunctionExpression, AstType::Function]));
const RUN_FUNCTIONS: RuleRunFunctionsImplemented = RuleRunFunctionsImplemented::Run;
}
impl RuleRunner for crate::rules::node::no_exports_assign::NoExportsAssign {
const NODE_TYPES: Option<&AstTypesBitset> =
Some(&AstTypesBitset::from_types(&[AstType::AssignmentExpression]));
+25 -1
View File
@@ -335,6 +335,7 @@ pub use crate::rules::nextjs::no_title_in_document_head::NoTitleInDocumentHead a
pub use crate::rules::nextjs::no_typos::NoTypos as NextjsNoTypos;
pub use crate::rules::nextjs::no_unwanted_polyfillio::NoUnwantedPolyfillio as NextjsNoUnwantedPolyfillio;
pub use crate::rules::node::global_require::GlobalRequire as NodeGlobalRequire;
pub use crate::rules::node::handle_callback_err::HandleCallbackErr as NodeHandleCallbackErr;
pub use crate::rules::node::no_exports_assign::NoExportsAssign as NodeNoExportsAssign;
pub use crate::rules::node::no_new_require::NoNewRequire as NodeNoNewRequire;
pub use crate::rules::node::no_path_concat::NoPathConcat as NodeNoPathConcat;
@@ -1396,6 +1397,7 @@ pub enum RuleEnum {
),
VitestWarnTodo(VitestWarnTodo),
NodeGlobalRequire(NodeGlobalRequire),
NodeHandleCallbackErr(NodeHandleCallbackErr),
NodeNoExportsAssign(NodeNoExportsAssign),
NodeNoNewRequire(NodeNoNewRequire),
NodeNoPathConcat(NodeNoPathConcat),
@@ -2178,7 +2180,8 @@ const VITEST_REQUIRE_LOCAL_TEST_CONTEXT_FOR_CONCURRENT_SNAPSHOTS_ID: usize =
const VITEST_WARN_TODO_ID: usize =
VITEST_REQUIRE_LOCAL_TEST_CONTEXT_FOR_CONCURRENT_SNAPSHOTS_ID + 1usize;
const NODE_GLOBAL_REQUIRE_ID: usize = VITEST_WARN_TODO_ID + 1usize;
const NODE_NO_EXPORTS_ASSIGN_ID: usize = NODE_GLOBAL_REQUIRE_ID + 1usize;
const NODE_HANDLE_CALLBACK_ERR_ID: usize = NODE_GLOBAL_REQUIRE_ID + 1usize;
const NODE_NO_EXPORTS_ASSIGN_ID: usize = NODE_HANDLE_CALLBACK_ERR_ID + 1usize;
const NODE_NO_NEW_REQUIRE_ID: usize = NODE_NO_EXPORTS_ASSIGN_ID + 1usize;
const NODE_NO_PATH_CONCAT_ID: usize = NODE_NO_NEW_REQUIRE_ID + 1usize;
const NODE_NO_PROCESS_ENV_ID: usize = NODE_NO_PATH_CONCAT_ID + 1usize;
@@ -2987,6 +2990,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VITEST_WARN_TODO_ID,
Self::NodeGlobalRequire(_) => NODE_GLOBAL_REQUIRE_ID,
Self::NodeHandleCallbackErr(_) => NODE_HANDLE_CALLBACK_ERR_ID,
Self::NodeNoExportsAssign(_) => NODE_NO_EXPORTS_ASSIGN_ID,
Self::NodeNoNewRequire(_) => NODE_NO_NEW_REQUIRE_ID,
Self::NodeNoPathConcat(_) => NODE_NO_PATH_CONCAT_ID,
@@ -3785,6 +3789,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::NAME,
Self::NodeGlobalRequire(_) => NodeGlobalRequire::NAME,
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::NAME,
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::NAME,
Self::NodeNoNewRequire(_) => NodeNoNewRequire::NAME,
Self::NodeNoPathConcat(_) => NodeNoPathConcat::NAME,
@@ -4627,6 +4632,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::CATEGORY,
Self::NodeGlobalRequire(_) => NodeGlobalRequire::CATEGORY,
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::CATEGORY,
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::CATEGORY,
Self::NodeNoNewRequire(_) => NodeNoNewRequire::CATEGORY,
Self::NodeNoPathConcat(_) => NodeNoPathConcat::CATEGORY,
@@ -5428,6 +5434,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::FIX,
Self::NodeGlobalRequire(_) => NodeGlobalRequire::FIX,
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::FIX,
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::FIX,
Self::NodeNoNewRequire(_) => NodeNoNewRequire::FIX,
Self::NodeNoPathConcat(_) => NodeNoPathConcat::FIX,
@@ -6423,6 +6430,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::documentation(),
Self::NodeGlobalRequire(_) => NodeGlobalRequire::documentation(),
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::documentation(),
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::documentation(),
Self::NodeNoNewRequire(_) => NodeNoNewRequire::documentation(),
Self::NodeNoPathConcat(_) => NodeNoPathConcat::documentation(),
@@ -8372,6 +8380,8 @@ impl RuleEnum {
.or_else(|| VitestWarnTodo::schema(generator)),
Self::NodeGlobalRequire(_) => NodeGlobalRequire::config_schema(generator)
.or_else(|| NodeGlobalRequire::schema(generator)),
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::config_schema(generator)
.or_else(|| NodeHandleCallbackErr::schema(generator)),
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::config_schema(generator)
.or_else(|| NodeNoExportsAssign::schema(generator)),
Self::NodeNoNewRequire(_) => NodeNoNewRequire::config_schema(generator)
@@ -9112,6 +9122,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(_) => "vitest",
Self::VitestWarnTodo(_) => "vitest",
Self::NodeGlobalRequire(_) => "node",
Self::NodeHandleCallbackErr(_) => "node",
Self::NodeNoExportsAssign(_) => "node",
Self::NodeNoNewRequire(_) => "node",
Self::NodeNoPathConcat(_) => "node",
@@ -11315,6 +11326,9 @@ impl RuleEnum {
Self::NodeGlobalRequire(_) => {
Ok(Self::NodeGlobalRequire(NodeGlobalRequire::from_configuration(value)?))
}
Self::NodeHandleCallbackErr(_) => {
Ok(Self::NodeHandleCallbackErr(NodeHandleCallbackErr::from_configuration(value)?))
}
Self::NodeNoExportsAssign(_) => {
Ok(Self::NodeNoExportsAssign(NodeNoExportsAssign::from_configuration(value)?))
}
@@ -12063,6 +12077,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(rule) => rule.to_configuration(),
Self::NodeGlobalRequire(rule) => rule.to_configuration(),
Self::NodeHandleCallbackErr(rule) => rule.to_configuration(),
Self::NodeNoExportsAssign(rule) => rule.to_configuration(),
Self::NodeNoNewRequire(rule) => rule.to_configuration(),
Self::NodeNoPathConcat(rule) => rule.to_configuration(),
@@ -12765,6 +12780,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(rule) => rule.run(node, ctx),
Self::VitestWarnTodo(rule) => rule.run(node, ctx),
Self::NodeGlobalRequire(rule) => rule.run(node, ctx),
Self::NodeHandleCallbackErr(rule) => rule.run(node, ctx),
Self::NodeNoExportsAssign(rule) => rule.run(node, ctx),
Self::NodeNoNewRequire(rule) => rule.run(node, ctx),
Self::NodeNoPathConcat(rule) => rule.run(node, ctx),
@@ -13467,6 +13483,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(rule) => rule.run_once(ctx),
Self::VitestWarnTodo(rule) => rule.run_once(ctx),
Self::NodeGlobalRequire(rule) => rule.run_once(ctx),
Self::NodeHandleCallbackErr(rule) => rule.run_once(ctx),
Self::NodeNoExportsAssign(rule) => rule.run_once(ctx),
Self::NodeNoNewRequire(rule) => rule.run_once(ctx),
Self::NodeNoPathConcat(rule) => rule.run_once(ctx),
@@ -14269,6 +14286,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(rule) => rule.run_on_jest_node(jest_node, ctx),
Self::NodeGlobalRequire(rule) => rule.run_on_jest_node(jest_node, ctx),
Self::NodeHandleCallbackErr(rule) => rule.run_on_jest_node(jest_node, ctx),
Self::NodeNoExportsAssign(rule) => rule.run_on_jest_node(jest_node, ctx),
Self::NodeNoNewRequire(rule) => rule.run_on_jest_node(jest_node, ctx),
Self::NodeNoPathConcat(rule) => rule.run_on_jest_node(jest_node, ctx),
@@ -14971,6 +14989,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(rule) => rule.should_run(ctx),
Self::VitestWarnTodo(rule) => rule.should_run(ctx),
Self::NodeGlobalRequire(rule) => rule.should_run(ctx),
Self::NodeHandleCallbackErr(rule) => rule.should_run(ctx),
Self::NodeNoExportsAssign(rule) => rule.should_run(ctx),
Self::NodeNoNewRequire(rule) => rule.should_run(ctx),
Self::NodeNoPathConcat(rule) => rule.should_run(ctx),
@@ -15965,6 +15984,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::IS_TSGOLINT_RULE,
Self::NodeGlobalRequire(_) => NodeGlobalRequire::IS_TSGOLINT_RULE,
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::IS_TSGOLINT_RULE,
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::IS_TSGOLINT_RULE,
Self::NodeNoNewRequire(_) => NodeNoNewRequire::IS_TSGOLINT_RULE,
Self::NodeNoPathConcat(_) => NodeNoPathConcat::IS_TSGOLINT_RULE,
@@ -16836,6 +16856,7 @@ impl RuleEnum {
}
Self::VitestWarnTodo(_) => VitestWarnTodo::HAS_CONFIG,
Self::NodeGlobalRequire(_) => NodeGlobalRequire::HAS_CONFIG,
Self::NodeHandleCallbackErr(_) => NodeHandleCallbackErr::HAS_CONFIG,
Self::NodeNoExportsAssign(_) => NodeNoExportsAssign::HAS_CONFIG,
Self::NodeNoNewRequire(_) => NodeNoNewRequire::HAS_CONFIG,
Self::NodeNoPathConcat(_) => NodeNoPathConcat::HAS_CONFIG,
@@ -17540,6 +17561,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(rule) => rule.types_info(),
Self::VitestWarnTodo(rule) => rule.types_info(),
Self::NodeGlobalRequire(rule) => rule.types_info(),
Self::NodeHandleCallbackErr(rule) => rule.types_info(),
Self::NodeNoExportsAssign(rule) => rule.types_info(),
Self::NodeNoNewRequire(rule) => rule.types_info(),
Self::NodeNoPathConcat(rule) => rule.types_info(),
@@ -18242,6 +18264,7 @@ impl RuleEnum {
Self::VitestRequireLocalTestContextForConcurrentSnapshots(rule) => rule.run_info(),
Self::VitestWarnTodo(rule) => rule.run_info(),
Self::NodeGlobalRequire(rule) => rule.run_info(),
Self::NodeHandleCallbackErr(rule) => rule.run_info(),
Self::NodeNoExportsAssign(rule) => rule.run_info(),
Self::NodeNoNewRequire(rule) => rule.run_info(),
Self::NodeNoPathConcat(rule) => rule.run_info(),
@@ -19062,6 +19085,7 @@ pub static RULES: std::sync::LazyLock<Vec<RuleEnum>> = std::sync::LazyLock::new(
),
RuleEnum::VitestWarnTodo(VitestWarnTodo::default()),
RuleEnum::NodeGlobalRequire(NodeGlobalRequire::default()),
RuleEnum::NodeHandleCallbackErr(NodeHandleCallbackErr::default()),
RuleEnum::NodeNoExportsAssign(NodeNoExportsAssign::default()),
RuleEnum::NodeNoNewRequire(NodeNoNewRequire::default()),
RuleEnum::NodeNoPathConcat(NodeNoPathConcat::default()),
+1
View File
@@ -722,6 +722,7 @@ pub(crate) mod vitest {
pub(crate) mod node {
pub mod global_require;
pub mod handle_callback_err;
pub mod no_exports_assign;
pub mod no_new_require;
pub mod no_path_concat;
@@ -0,0 +1,278 @@
use std::borrow::Cow;
use lazy_regex::Regex;
use schemars::JsonSchema;
use serde::Deserialize;
use oxc_ast::{AstKind, ast::FormalParameters};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
AstNode,
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn handle_callback_err_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Expected error to be handled.")
.with_help("Handle the error or rename the parameter if it's not an error.")
.with_label(span)
}
#[derive(Debug, Clone, JsonSchema)]
enum ErrorPattern {
Plain(String),
Regex(Regex),
}
impl Default for ErrorPattern {
fn default() -> Self {
Self::Plain("err".to_string())
}
}
impl ErrorPattern {
fn matches(&self, name: &str) -> bool {
match self {
Self::Plain(s) => name == s,
Self::Regex(r) => r.is_match(name),
}
}
}
fn deserialize_error_pattern<'de, D>(deserializer: D) -> Result<Box<ErrorPattern>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <Cow<str>>::deserialize(deserializer)?;
let pattern = {
if s.starts_with('^') {
Regex::new(&s).map_or_else(|_| ErrorPattern::Plain(s.to_string()), ErrorPattern::Regex)
} else {
ErrorPattern::Plain(s.to_string())
}
};
Ok(Box::new(pattern))
}
/// The rule takes a single string option: the name of the error parameter.
///
/// This can be either:
/// - an exact name (e.g. `"err"`, `"error"`)
/// - a regexp pattern (e.g. `"^(err|error)$"`)
///
/// If the configured name of the error variable begins with a `^` it is considered to be a regexp pattern.
///
/// Default: `"err"`.
#[derive(Debug, Clone, Default, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default)]
pub struct HandleCallbackErrConfig(String);
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
pub struct HandleCallbackErr(
#[serde(deserialize_with = "deserialize_error_pattern")] Box<ErrorPattern>,
);
declare_oxc_lint!(
/// ### What it does
///
/// This rule expects that when you're using the callback pattern in Node.js you'll handle the error.
///
/// ### Why is this bad?
///
/// In Node.js, a common pattern for dealing with asynchronous behavior is called the callback pattern.
/// This pattern expects an `Error` object or `null` as the first argument of the callback.
/// Forgetting to handle these errors can lead to some really strange behavior in your application.
///
/// ```js
/// function loadData (err, data) {
/// doSomething(); // forgot to handle error
/// }
/// ```
///
/// ### Examples
///
/// Examples of **incorrect** code for this rule with the default `"err"` parameter name:
/// ```js
/// function loadData (err, data) {
/// doSomething();
/// }
/// ```
///
/// Examples of **correct** code for this rule with the default `"err"` parameter name:
/// ```js
/// function loadData (err, data) {
/// if (err) {
/// console.log(err.stack);
/// }
/// doSomething();
/// }
///
/// function generateError (err) {
/// if (err) {}
/// }
/// ```
///
/// Examples of correct code for this rule with a sample `"error"` parameter name:
///```js
/// function loadData (error, data) {
/// if (error) {
/// console.log(error.stack);
/// }
/// doSomething();
/// }
///```
HandleCallbackErr,
node,
restriction,
config = HandleCallbackErrConfig,
);
impl Rule for HandleCallbackErr {
fn from_configuration(value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
serde_json::from_value::<DefaultRuleConfig<Self>>(value).map(DefaultRuleConfig::into_inner)
}
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
match node.kind() {
AstKind::Function(func) => {
self.check_for_error(&func.params, ctx);
}
AstKind::ArrowFunctionExpression(arrow_func) => {
self.check_for_error(&arrow_func.params, ctx);
}
_ => {}
}
}
}
impl HandleCallbackErr {
fn check_for_error(&self, params: &FormalParameters, ctx: &LintContext) {
if let Some(first_param) = params.items.first()
&& let Some(ident) = first_param.pattern.get_binding_identifier()
&& self.0.matches(&ident.name)
&& ctx.symbol_references(ident.symbol_id()).count() == 0
{
ctx.diagnostic(handle_callback_err_diagnostic(ident.span));
}
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
("function test(error) {}", None),
("function test(err) {console.log(err);}", None),
("function test(err, data) {if(err){ data = 'ERROR';}}", None),
("var test = function(err) {console.log(err);};", None),
("var test = function(err) {if(err){/* do nothing */}};", None),
("var test = function(err) {if(!err){doSomethingHere();}else{};}", None),
("var test = function(err, data) {if(!err) { good(); } else { bad(); }}", None),
("try { } catch(err) {}", None),
(
"getData(function(err, data) {if (err) {}getMoreDataWith(data, function(err, moreData) {if (err) {}getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});});});",
None,
),
("var test = function(err) {if(! err){doSomethingHere();}};", None),
(
"function test(err, data) {if (data) {doSomething(function(err) {console.error(err);});} else if (err) {console.log(err);}}",
None,
),
(
"function handler(err, data) {if (data) {doSomethingWith(data);} else if (err) {console.log(err);}}",
None,
),
(
"function handler(err) {logThisAction(function(err) {if (err) {}}); console.log(err);}",
None,
),
("function userHandler(err) {process.nextTick(function() {if (err) {}})}", None),
(
"function help() { function userHandler(err) {function tester() { err; process.nextTick(function() { err; }); } } }",
None,
),
("function help(done) { var err = new Error('error'); done(); }", None),
("var test = err => err;", None),
("var test = err => !err;", None),
("var test = err => err.message;", None),
(
"var test = function(error) {if(error){/* do nothing */}};",
Some(serde_json::json!(["error"])),
),
(
"var test = (error) => {if(error){/* do nothing */}};",
Some(serde_json::json!(["error"])),
),
(
"var test = function(error) {if(! error){doSomethingHere();}};",
Some(serde_json::json!(["error"])),
),
(
"var test = function(err) { console.log(err); };",
Some(serde_json::json!(["^(err|error)$"])),
),
(
"var test = function(error) { console.log(error); };",
Some(serde_json::json!(["^(err|error)$"])),
),
(
"var test = function(anyError) { console.log(anyError); };",
Some(serde_json::json!(["^.+Error$"])),
),
(
"var test = function(any_error) { console.log(anyError); };",
Some(serde_json::json!(["^.+Error$"])),
),
(
"var test = function(any_error) { console.log(any_error); };",
Some(serde_json::json!(["^.+(e|E)rror$"])), // spellchecker:disable-line
),
];
let fail = vec![
("function test(err) {}", None),
("function test(err, data) {}", None),
("function test(err) {errorLookingWord();}", None),
("function test(err) {try{} catch(err) {}}", None),
("function test(err, callback) { foo(function(err, callback) {}); }", None),
("var test = (err) => {};", None),
("var test = function(err) {};", None),
("var test = function test(err, data) {};", None),
("var test = function test(err) {/* if(err){} */};", None),
("function test(err) {doSomethingHere(function(err){console.log(err);})}", None),
("function test(error) {}", Some(serde_json::json!(["error"]))),
(
"getData(function(err, data) {getMoreDataWith(data, function(err, moreData) {if (err) {}getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});}); });",
None,
),
(
"getData(function(err, data) {getMoreDataWith(data, function(err, moreData) {getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});}); });",
None,
),
(
"function userHandler(err) {logThisAction(function(err) {if (err) { console.log(err); } })}",
None,
),
(
"function help() { function userHandler(err) {function tester(err) { err; process.nextTick(function() { err; }); } } }",
None,
),
(
"var test = function(anyError) { console.log(otherError); };",
Some(serde_json::json!(["^.+Error$"])),
),
("var test = function(anyError) { };", Some(serde_json::json!(["^.+Error$"]))),
(
"var test = function(err) { console.log(error); };",
Some(serde_json::json!(["^(err|error)$"])),
),
];
Tester::new(HandleCallbackErr::NAME, HandleCallbackErr::PLUGIN, pass, fail).test_and_snapshot();
}
@@ -0,0 +1,143 @@
---
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err) {}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err, data) {}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err) {errorLookingWord();}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err) {try{} catch(err) {}}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err, callback) { foo(function(err, callback) {}); }
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:45]
1 │ function test(err, callback) { foo(function(err, callback) {}); }
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:13]
1 │ var test = (err) => {};
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:21]
1 │ var test = function(err) {};
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:26]
1 │ var test = function test(err, data) {};
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:26]
1 │ var test = function test(err) {/* if(err){} */};
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(err) {doSomethingHere(function(err){console.log(err);})}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:15]
1 │ function test(error) {}
· ─────
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:18]
1 │ getData(function(err, data) {getMoreDataWith(data, function(err, moreData) {if (err) {}getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});}); });
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:18]
1 │ getData(function(err, data) {getMoreDataWith(data, function(err, moreData) {getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});}); });
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:61]
1 │ getData(function(err, data) {getMoreDataWith(data, function(err, moreData) {getEvenMoreDataWith(moreData, function(err, allOfTheThings) {if (err) {}});}); });
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:22]
1 │ function userHandler(err) {logThisAction(function(err) {if (err) { console.log(err); } })}
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:40]
1 │ function help() { function userHandler(err) {function tester(err) { err; process.nextTick(function() { err; }); } } }
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:21]
1 │ var test = function(anyError) { console.log(otherError); };
· ────────
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:21]
1 │ var test = function(anyError) { };
· ────────
╰────
help: Handle the error or rename the parameter if it's not an error.
⚠ eslint-plugin-node(handle-callback-err): Expected error to be handled.
╭─[handle_callback_err.tsx:1:21]
1 │ var test = function(err) { console.log(error); };
· ───
╰────
help: Handle the error or rename the parameter if it's not an error.