-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
feat(eslint-plugin): add new rule no-floating-promises #495
feat(eslint-plugin): add new rule no-floating-promises #495
Conversation
Codecov Report
@@ Coverage Diff @@
## master #495 +/- ##
==========================================
+ Coverage 94.12% 94.19% +0.07%
==========================================
Files 104 105 +1
Lines 4271 4323 +52
Branches 1166 1185 +19
==========================================
+ Hits 4020 4072 +52
Misses 146 146
Partials 105 105
|
Thanks for the contribution. const x = Promise.resolve()
x.then(() => {})
x.catch(() => {}) i.e. you have to The docs LGTM, i haven't reviewed the rule code itself yet. |
The code shown is invalid per the current implementation, but only on line 2. Specifically, the rule requires two handlers to be passed if the final call is a const x = Promise.resolve();
x.then(() => {}, () => {}); // Valid because a rejection handler is provided
x.catch(() => {}); // Valid because rejections are handled
x.then(() => {}).catch(() => {}); // Valid because a catch appears at the end of the chain And yes, if you const x = Promise.resolve();
const y = x.then(() => {});
y.catch(() => {}); |
Adds the equivalent of TSLint's `no-floating-promises` rule. Fixes typescript-eslint#464
f897a68
to
6bb84bd
Compare
Realized that I made the check for what constituted a floating promise too aggressive. Softened it to be more conservative in raising errors and intelligently inspect more types of expressions. |
just a tip - you should avoid force pushing ammended commits after you've raised a PR. We squash merge to master anyways, so it doesn't matter if there's junk commits in your branch. |
Sorry about that. I'll be sure to break further updates into separate commits. As a side note, have you considered adding a CONTRIBUTING.md file to the repository? I find that to be a useful place to codify practices like this in a discoverable way. |
Probably should now as we're getting more new contributors. I never bothered because I was under the impression most people didn't read them, and I didn't have much contributing information that I thought really needed to be codified.. Though it's surprising for me that a large portion of our contributors use this force push workflow. I assume that it's because people are using a tool like git town? |
I split time between GitHub and Azure DevOps depending on project and the latter doesn't have the same issue with diffing revisions on the same force pushed commits, making it less of a concern. I have also contributed to projects in the past that prefer to rebase merge and therefore like having the single commit despite the complications with reviewing. For me personally, I just use plain git from the command line but I have aliases set up for As for contributing files, there will definitely be a large number of people who won't read it, but it gives an easy thing to refer people to when they do things wrong. You can even add a pull request template that has a checkbox for "following instructions in the CONTRIBUTING.md file" which will get more people to read it (as long as it's not too long). |
First off, thank you for implementing this in ESLint. I don't intend this comment to detour from the work put in here. This is one of the rules I was really missing from ESLint's Typescript implementation. I noticed this implementation specifically checks the sub-expression on void expressions. Some would find that useful, there is actually a good discussion here about this palantir/tslint#4653 -- however, I am of the camp where using Would we consider perhaps adding configuration to this rule to support both cases? I have no problem putting in the corresponding work if that sounds reasonable. |
@jonathanrdelgado ah interesting, hadn't seen that usage pattern before but definitely not opposed to an option to allow it if it's a pattern people use. I would still be inclined to make the behavior as currently implemented the default so that people get the "safer" behavior unless they explicitly opt out. With that said, I think the main question is whether the option is a one-off specifically for void expressions (e.g. The latter is more flexible, but has a couple of problems:
For these reasons, perhaps it's easier to start with |
my opinion is that you shouldn't ever use the void operator in executed code. |
I think those are fair points and that seems reasonable to me. I'll move my existing void statements to disable comments. Thank you both for your input. Looking forward to this rule being included in future versions! |
Anything else I can do to help get this PR across the line? |
@princjef we like to have 2 approvals for feature PRs before merging. That being said, this PR has been approved for a month, so it's about time for a merge. |
Regarding the use of IMO:
|
@glen-84 - please avoid commenting on old, merged PRs. Opening a new issue is much preferred. |
Adds the equivalent of TSLint's
no-floating-promises
rule. Fixes #464.Some notes about the implementation:
isThenable
function of tsutils to check whether a value should be handled, because thenable does not mandate the ability to reject/catch. Instead, a similar function is defined which is in line with the definition of a promise in A+ by requiring two parameters to exist in the.then()
definition..catch()
call, unlike the previous rule. This is because a.catch()
call with no function provided does not actually catch anything..then()
functions defined using rest params. For an initial implementation that has to check multiple positional parameters, this seemed like an substantial complication for a highly unlikely scenario, leading to at worst some errors being missed. The functionality can be added if desired.