0

Basically had an async function in JavaScript (nodejs app) that returned a list...unfortunately I forgot to call await on this testFunction(x, y) and so it broke some code in production. Is there a linting rule that would catch this? Is there a test I can write to ensure that this won't break because I forgot to call await (it seems like linting is the way to ensure errors like this are caught)?

const testFunction = async (x, y) => {
   let z = await someFunction();
  //..some code that returns a list after processing z
}
Nona
  • 5,302
  • 7
  • 41
  • 79
  • await will always gets called. Oh, you're looking for a lint rule. I don't see how a linter is ever going to know if a function is async or not. – evolutionxbox Jan 26 '21 at 21:18
  • What editor are you using? I would think your editor could have caught that. – Pytth Jan 26 '21 at 21:20
  • 8
    Sounds more like a lack of tests problem than a linter one... – James Jan 26 '21 at 21:20
  • It's perfectly possible that you actually want to store the Promise in `z` instead; I don't think a linter can analyze your code this deep (speaking as a layperson with regard to linters though). Still, this is were testing comes in. –  Jan 26 '21 at 21:21
  • 1
    https://palantir.github.io/tslint/rules/no-floating-promises/ Perhaps this could be of use? This is what I found after rabbit holing through Google. – Adam Kerik Jan 26 '21 at 21:21
  • @AdamKerik That doesn't help with OP's problem unfortunately. –  Jan 26 '21 at 21:22
  • It's a tricky one, even for a Linter to pick up. Because not calling await on a Promise may indeed be something your want to do.. Think `Promise.all` etc, or even starting a new Promise to act like a fork.. – Keith Jan 26 '21 at 21:23
  • 1
    You can go with TypeScript/Flow and then you'd get an error when using a Promise as if it's another type of value. Otherwise the only linter rule that can help you here is the one that mandates async functions to have an `await` but that doesn't help if you have to use `await` twice but you've only added it once. Fundamentally, this should have been caught in testing WAY before production. – VLAZ Jan 26 '21 at 21:23
  • 1
    @AdamKerik "TS Only". – VLAZ Jan 26 '21 at 21:24
  • @James - it is, this is a code base that was built with no tests, so the team is adding as we can. You can imagine why issues like this crop up. – Nona Jan 26 '21 at 21:24
  • 1
    @Nona even outside *automated* tests, you should at least manually checking if what you did was correct. Then you should have *testers*. There are three levels of tests that were skipped. Not to mention code reviews. – VLAZ Jan 26 '21 at 21:25
  • `/await /.test(testFunction)` – dandavis Jan 26 '21 at 21:26
  • You can implement TypeScript to your project for checking return value types of everything. You can declare to function's return type and if you forget this await, linter gone mad. – Mücahit Inel Jan 26 '21 at 21:29
  • This answer mentions an eslint rule called "require-await": [Check if a js function is called using await](https://stackoverflow.com/a/63765236/3113485). Docs: [ESLint Disallow async functions which have no await expression (require-await)](https://eslint.org/docs/rules/require-await), it seems to check that async functions contain at least one `await`, not exactly the same. – terrymorse Jan 26 '21 at 21:36
  • @terrymorse it doesn't fundamentally solve the problem of broken code going into production. This is a process failure a lot more than a tool deficiency. And what coverage ESLint can offer doesn't fix that. – VLAZ Jan 26 '21 at 21:58
  • @VLAZ Possibly a static type checker (JSDoc, Flow) could help. Using JSDoc, I get this warning: `let str = asyncFn() : Initializer type Promise is not assignable to variable type string`. – terrymorse Jan 26 '21 at 22:27

0 Answers0