New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider removing no-callback-literal
rule
#1352
Comments
I strongly recommend removing this rule. First of all, the use-cases of callback with literal is much more common than we expect, currently we can only workaround by change callback name. Secondly, as a non-configurable lint library, I think standard should be more careful for adding new rules, especially when the rules are not very common. Since we cannot configure it, we have to accept. |
Thanks for the feedback @yibn2008, considering it for the next version of |
I personally like this rule, the err-first callback-style is very widely used and I think it's nice to have to be explicit when not following it... I don't have that strong of an opinion though... |
I suggested this rule originally, but realize it has limited value and is susceptible to false positives. |
It was previously in the "desirable to turn on" section, but it complains about valid code and is considered to be removed: https://github.com/standard/eslint-plugin-standard/issues/27
It was previously in the "desirable to turn on" section, but it complains about valid code and is considered to be removed: https://github.com/standard/eslint-plugin-standard/issues/27
I'm writing client side code. e.g.: const askTheServerForSomething = (callback) => {
post()
.then(callback({x: 1})) // just an example. can be anything: object, string, boolean...
.catch(ex => handle(ex))
} standard complains about it. |
@targumon In your example, the problematic pattern is that you have no way of handling errors from the const askTheServerForSomething = (callback) => {
post()
.then(callback(null, {x: 1}))
.catch(ex => callback(ex))
} This ties into having self-contained functions that don't modify global state. In your example it seems like some global handler are invoked in the case of an error in the askTheServerForSomething((err, res) => {
if (err) return globalErrorHandler(err)
// ...
}) It's a bit hard to make better recommendations based on the small example you provided, but I'd be happy to take on any follow up questions/discussion |
@LinusU Yes, my example was only meant to illustrate the gist of the actual code. So it's not like I'm ignoring the errors. And as I said before the linter doesn't complain if I use a different name: const doSomething = (cbFunc) => {
post()
.then(cbFunc({x: 1}))
} This is a "cousin" of the const foo = (er) => { // this passes
bar()
} Anyway, thanks for your detailed reply - I learned from it! ^_^ |
I just encountered this error for the first time. In the initial issue (issue #623), @xjamundx mentioned that passing a string "can lead to all sorts of weird bugs". What kind of weird bugs? It's not a big deal of course, but I am curious: what is this rule protecting me from? It's a tall order, and something I am sure has been suggested before, but a directory of rules/errors similar to https://eslint.org/docs/rules/ explaining each rules' behaviour and reasoning would be a delight ✨ Thank you for all your hard work on this library. |
@bookercodes The simplest explanation looks something like this... doSomething(function(err, data) {
if (err) return console.warn(err.stack) // undefined
console.log(data)
}) Or even this example, where did you have the error reading the file? Without the stack trace generated by readFile(filename, function(err, data) {
if (err) console.log(err) // error reading file
}) My background as of late has been large enterprise apps where enforcing patterns like this helps save a ton of debugging time. We once had an issue like this where our uncaught exception handler was reporting Of course there are smaller apps and other patterns that wouldn't have these issues. There are also some systems which rely on passing other data types to a callback function |
That is a very good point. In my case, I was dealing with an AWS Lambda function |
@bookercodes we are running our entire infrastructure on Lambda and have this rule enabled, I would absolutely recommend passing errors instead of strings 👍 Passing the entire error will also give you the entire stack trace in the CloudWatch logs instead of just the error messages |
So any plans to remove this rule? It's very inconvenient, and the way of detecting if a function is a callback by its name is rather hackish. |
@vokar I still don't think that we should remove this rule. Would you mind sharing some examples of the code that you are having problem with? Knowing what the problem is will help us to decide if we want to remove this, or tweak it in some way... |
We have that! See: https://standardjs.com/rules.html |
There are a few outstanding problems with this rule:
module.exports = a
function a (cb) {
cb(...[new Error(''), 1, 2]) // Unexpected literal in error position of callback.
} I wonder if anyone has the interest to get it fixed up? Or perhaps we can see if the
|
I opened an issue asking if ESLint wants to adopt If they adopt it, then we can just keep the rule enabled. It's been around for a long time and as folks continue to switch to async-await, I see this becoming more of a non-issue. Although, maybe as folks migrate Node.js-style callbacks to async-await, more of the remaining callback cases will be false positives like what we've seen in this thread? @LinusU do you have thoughts? |
I think this is a good approach.
Yeah I've personally never been bit by a false positive here, but I have seen many example of bad code that this rule would have prevented. All in all, I would prefer to have it enabled but don't feel super strongly about it |
|
Okay, let's keep the rule for now. Still open to potentially removing it in a few years once async-await has near 100% usage over callbacks. Feel free to continue discussion, but closing this issue for now. |
Does this rule exclude My |
|
Hi, is this fixed? or is there a separate issue for this? @feross |
@nikugogoi doesn't seem like it's been fixed, and I cannot find an open issue. Would you be able to open an issue here? |
Another case where this rule returns a false positive: I'm writing an function validate(_, value, callback) {
if (!value) return callback([new Error('Required')])
callback()
} As mentioned in some of the prior comments, it's possible to get around this rule by renaming the |
See discussion at: standard/eslint-plugin-standard#12 (comment)
The text was updated successfully, but these errors were encountered: