-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Bug: [@typescript-eslint/no-floating-promises] Not catching promises assigned to a variable #10822
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
Comments
Duplicate of #3359, #5749, and #6766. Assigning a variable to a Promise is one of the valid ways to handle it.
Yup, there is. Linking this to #8088, which tracks us overhauling the |
Assigning it to a variable is NOT handling it. no-unused-vars isn't going to help because it our real world examples the variables are used. I did this as a minimal reproduction. The linter used to be smart enough to check whether or not the variable was ever awaited, why take that away? I've got to be missing something :( |
Hmm, I thought the docs called that out more clearly but yeah I'm not seeing anything obvious. Maybe we lost a mention during previous docs changes? The closest we have now is the Tip which says "no-floating-promises only detects apparently unhandled Promise statements. See no-misused-promises for detecting code that provides Promises to logical locations such as if statements." |
Between this and the disastrous flat file change, I guess it's time to start digging into Biomejs. Thanks for the quick response y'all! |
It's true. It's important to think of const promise = Promise.reject('foo');
console.log(promise); // doesn't handle the promise
await Promise.all([promise]); // does handle the promise
function terminatePromise(x: Promise<unknown>): void {
x.catch(e => console.error(e);
}
terminatePromise(promise); // does handle the promise To keep the rule logic understandable for authors and for users, its purview is limited to looking for suspicious promise-valued statements, rather than attempting to analyze what you do with variables/expressions. |
We're defining "handling" differently 😄. From the rule's perspective, putting it in a variable that is then used satisfies that criteria. From the perspective of the linter, as long as something uses the variable, it's very hard to know whether that variable is appropriately handled as a Promise. At first glance it seems like a straightforward heuristic could be "is the variable declare function doWork(): Promise<void>; async function mainReturns() {
const work = doWork();
return work;
} declare function processInQueue(task: Promise<void>): void;
async function mainProcesses() {
const work = doWork();
processInQueue(task);
} declare function log(data: unknown): void;
async function mainLogs() {
const work = doWork();
log(task);
} Each could be argued either way:
Can you share a motivating example? I'd love to take a look - even if it can't be pared down to a truly "minimal" reproduction easily.
Unless there's a not-yet-known bug, I don't think it ever was? Looking through https://github.com/typescript-eslint/typescript-eslint/blob/main/CHANGELOG.md, nothing in recent years pops out to me as changing how it handles variables within functions. But if you can provide a complex reproduction showing an older version missing this, we can take a deeper look at the potential regression.
Your timing is good, they just shipped their own version of no-floating-promises: biomejs/biome#4956 -> biomejs/biome#4911. I don't see it on their site yet, but that should come soon. Filed biomejs/website#1732 in the meantime to ask (I'm sure I'm missing something myself). That being said, I'm pretty sure Biome's no-floating-promises equivalent also doesn't flag variables 😄. It only reports statements such as function calls: https://github.com/biomejs/biome/pull/4911/files#diff-fa08cc1e3d0164c82fa5c7869713b76567a409e870a46a4abaaae45b581f8507R23. |
Good luck with this. The flat config break was upstream in eslint core, a separately maintained project, and |
Thanks @JoshuaKGoldberg ! I'm 99.99 percent sure I have a case of hanging tests because something async isn't handled somewhere. I'm just trying to find it :) Without lint/compiler help, I'm down to removing every test and adding them back one at a time, but it is what it is :) I also realize that the flat config was upstream eslint core. I also know that I have used eslint since v1 and it's always been a pleasure to use, helped me find bugs, and never got in my way until v8. These days I'm wasting so much time on it :( I'll maybe end up running eslint/biomejs side by side for awhile and see how it goes. I just need to get back to doing real work, not spending so much time on this :) |
Before You File a Bug Report Please Confirm You Have Done The Following...
Playground Link
https://typescript-eslint.io/play/#ts=4.8.4&fileType=.ts&code=PQKgBApgzgNglgOwC5gAJIJ4AdoGMBOcWSAtNPMsAgPYkC2cUArlBACYlb7UOtQBcYAOQR83fELAhgAKFCRYiFOmx5CxMoso0SAMxjUAhkkQBzTt17RBIsdQlTZM3NQRQUbagGUeEJAAszAEEoDARcMABeMENQ8LAACgBKKIA%2BMABvGTAwfD8mfAQwAAVLRggAOjyoahgANwgE5LTM7Jzc-MKwACIAETg2MBq6P0CEU26AbjaAXySZGZlnV3cwUz8fEYCzKLBPTdHguNxkybBgYDAvf2omGEHRcSHEXAg1jd9t8bBGMAQIBr4MD%2BQwINgwdhLfafMamEJhE5JabLNy1SoGUwJboAdX8GD%2B1DA%2BiMJm%2BXB45UgdnwAH5ugAad5IA5fUxIpZAA&eslintrc=N4KABGBEBOCuA2BTAzpAXGUELjAXxDyA&tsconfig=N4KABGBEDGD2C2AHAlgGwKYCcDyiAuysAdgM6QBcYoEEkJemy0eAcgK6qoDCAFutAGsylBm3TgwAXxCSgA&tokens=false
Repro Code
ESLint Config
tsconfig
Expected Result
I expected that line 10 would get a no-floating-promises error since the promise doesn't meet any of these criteria
Actual Result
No error is reported
Additional Info
We just upgraded from eslint 8 to 9 and I'm kind of shocked to see this not working. It's one of the most common issues I've seen in jest tests and poorly typed code. Am I missing something? Is there another rule meant to catch this promise?
The text was updated successfully, but these errors were encountered: