Skip to content

feat(eslint-plugin): [return-await] add option to report in error-handling scenarios only, and deprecate "never" #9364

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

Merged

Conversation

kirkwaiblinger
Copy link
Member

@kirkwaiblinger kirkwaiblinger commented Jun 15, 2024

PR Checklist

Overview

Just adds an option to ignore return-await concerns outside of scenarios relevant for error-handling

If anyone has suggestions on a better name for the option, please let me know!

NOTE

This is targeted against main for now, but it may make sense to target v8 instead. Not because it's a breaking change, but because its only purpose for existing is in service of #8667, which is a breaking change (if we do retarget to v8, it may also make sense to adjust the configs in the same PR) Was decided to keep this target to v7/main

@typescript-eslint
Copy link
Contributor

Thanks for the PR, @kirkwaiblinger!

typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community.

The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately.

Thanks again!


🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint.

Copy link

netlify bot commented Jun 15, 2024

Deploy Preview for typescript-eslint ready!

Name Link
🔨 Latest commit 8cd6116
🔍 Latest deploy log https://app.netlify.com/sites/typescript-eslint/deploys/669955902e6d9c000844475b
😎 Deploy Preview https://deploy-preview-9364--typescript-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 94 (no change from production)
Accessibility: 100 (no change from production)
Best Practices: 92 (no change from production)
SEO: 90 (no change from production)
PWA: 80 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify site configuration.

@kirkwaiblinger kirkwaiblinger changed the title enhancement(eslint-plugin): [return-await] add option to report in error-handling scenarios only feat(eslint-plugin): [return-await] add option to report in error-handling scenarios only Jun 15, 2024
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Detective Harris from South Park saying "NICCCE"

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
@@ -271,92 +314,69 @@ export default createRule({
const type = checker.getTypeAtLocation(child);
const isThenable = tsutils.isThenableType(checker, expression, type);
Copy link
Member Author

@kirkwaiblinger kirkwaiblinger Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github's diffing gets real confused about what actually changed here if you don't use the "ignore whitespace" here. Be sure to use that.

Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking on the docs 🤔

| always | `return await promise;` | `return await promise;` | ✅ Yes! |
| in-try-catch | `return promise;` | `return await promise;` | ✅ Yes! |
| error-handling-correctness-only | don't care 🤷 | `return await promise;` | 🟡 Okay to use, but the above options would be preferable. |
| never | `return promise;` | `return promise;` | ❌ No! |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Docs]

❌ No!

Well, if the option should never be used... why would we want to include it at all? It's not clear from this table or the ## `never` section why we have that. Maybe a solution to this would be to mention that never is only included for compatibility with the base rule?

Copy link
Member Author

@kirkwaiblinger kirkwaiblinger Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documenting a private conversation for visibility:


never is only included for compatibility with the base rule

There is no evidence that this is or ever was the case; see #994.


Plan to resolve this comment: tentative plan to deprecate 'never' as part of this PR. Getting that process started imminently.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

filed #9433

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorporated #9433 into this PR

Comment on lines 297 to 299
### Options Summary

| Option | Ordinary Context <br/> (stylistic preference) | Error Handling Context <br/> (catches subtle control flow bugs) | Should I use? |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Docs] I think this table is pretty useful. Proposal: how about moving this to within the ## Options early on, to prime folks with it before they dive into the options?

I also think it would be useful to mention in each option's section the pros & cons of that option. Right now, the always section just says "Requires that all returned promises are awaited.". It doesn't mention the option being preferred, or why it's preferred.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposal: how about moving this to within the ## Options early on, to prime folks with it before they dive into the options?

Yeah, that was actually my first approach, but i was waffling on how to go about defining an error-handling context since that's required before the table... and I went with this approach out of laziness. I agree that putting it first would be better, though, so I'll give it another stab 🙂

I also think it would be useful to mention in each option's section the pros & cons of that option. Right now, the always section just says "Requires that all returned promises are awaited.". It doesn't mention the option being preferred, or why it's preferred.

Feels like we're venturing into scope creep territory, but at the same time, we probably don't want this option to go out without good supporting docs 🤔 Will try to incorporate this 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made changes in this area. I definitely think the result is much better! Thanks for making the suggestions.

@JoshuaKGoldberg JoshuaKGoldberg added the awaiting response Issues waiting for a reply from the OP or another party label Jun 25, 2024
kirkwaiblinger and others added 2 commits June 24, 2024 23:04
Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
Comment on lines 223 to 225
Same as `in-try-catch`, except _only_ enforces Promises be awaited within the
error handling contexts explained under that option. Outside of error-handling
contexts, returned Promises are ignored, whether awaited or not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't wrap lines by line width

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh. not sure how that happened. In any case this has been fixed/superseded 👍

@phaux
Copy link
Contributor

phaux commented Jul 6, 2024

Maybe change the option so that instead of a string it's an object:

{
  default: "always" | "never" | "ignore", 
  inTryCatch?: "always" | "never" | "ignore", // undefined means "same as default" 
}

And make the string options aliases for backward compatibility:

  • "always" - { default: "always" }
  • "in-try-catch" - { default: "never", inTryCatch: "always" }
  • "never" - { default: "never" }

The new option would be { default: "ignore", inTryCatch: "always" }

In the future, there could be more conditions added. For example, someone might want to use "always" but make an exception for single-line arrow functions to make them less noisy:

/* eslint @typescript-eslint/promise-function-async: "error" */
/* eslint @typescript-eslint/return-await: ["error", { default: "always", inArrowFunction: "ignore" }] */

promise.then(async (v) => doSomethingAsync(v)) // allowed

@github-actions github-actions bot removed the awaiting response Issues waiting for a reply from the OP or another party label Jul 8, 2024
Copy link

codecov bot commented Jul 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.40%. Comparing base (dd965a4) to head (8cd6116).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9364      +/-   ##
==========================================
- Coverage   88.40%   88.40%   -0.01%     
==========================================
  Files         422      422              
  Lines       14652    14650       -2     
  Branches     4287     4285       -2     
==========================================
- Hits        12953    12951       -2     
  Misses       1374     1374              
  Partials      325      325              
Flag Coverage Δ
unittest 88.40% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
packages/eslint-plugin/src/rules/return-await.ts 97.39% <100.00%> (-0.05%) ⬇️

@Josh-Cena
Copy link
Member

I thought about the object API (which I mentioned in the linked issue), but I now don't like it. It creates a lot of "dubious combinations", for example you would never want { default: "always", inTryCatch: "never" }.

In the future, there could be more conditions added. For example, someone might want to use "always" but make an exception for single-line arrow functions to make them less noisy:

You should either not mark it as async (which is even less noisy), or add the await. I don't think we should accommodate that style as that's not really the spirit of this rule.

@kirkwaiblinger kirkwaiblinger changed the title feat(eslint-plugin): [return-await] add option to report in error-handling scenarios only feat(eslint-plugin): [return-await] add option to report in error-handling scenarios only, and deprecate "never" Jul 14, 2024
@kirkwaiblinger kirkwaiblinger added this to the 8.0.0 milestone Jul 15, 2024
Copy link
Member

@JoshuaKGoldberg JoshuaKGoldberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoohoo! Happy to finally have this thing modernized! 👏 🔥

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
@kirkwaiblinger kirkwaiblinger force-pushed the return-await-unopinionated branch from 3892d64 to b27b673 Compare July 16, 2024 21:27
@kirkwaiblinger kirkwaiblinger requested review from JoshuaKGoldberg and a team July 16, 2024 21:29
Josh-Cena
Josh-Cena previously approved these changes Jul 18, 2024
Copy link
Member

@Josh-Cena Josh-Cena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two optional nits; otherwise 🛳

@kirkwaiblinger kirkwaiblinger merged commit 970f3f1 into typescript-eslint:main Jul 18, 2024
65 checks passed
@kirkwaiblinger kirkwaiblinger deleted the return-await-unopinionated branch July 18, 2024 18:16
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deprecate return-await option "never" Enhancement: [return-await] Option for unopinionated "in-try-catch"
4 participants