Using ‘return’ vs ‘return await’

Anyone who has been coding Javascript for a while has been on the journey of callbacks, then promises, then the oh-so wonderful async/await syntax. In 2022, there’s really not much of a reason to use anything other than async/await (except for when a dependent library forces you to use callbacks).
ESLint has a variety of standards, and one of them encourages a performance improvement in your JS code. The no-return-await rule encourages us not to await promises in a function where we don’t use the value. https://eslint.org/docs/latest/rules/no-return-await
On the surface, this is great and makes sense. But some devs who jumped straight into async/await syntax might misunderstand what’s happening under-the-hood, and might even introduce a bug into the code base that skips a catch block, in the name of performance. If you carefully read the guidance pages of most ESLint rules, there are sometimes valid moments to push back on the rule. This rule makes it sound like you should never use ‘return await …;’. But in fact…

Let’s dive in with an example. https://jsfiddle.net/0g1zjouL/3/ This JSFiddle shows two variants of calling an asynchronous backend fetch API. One variant returns the promise, but the 2nd variant is identical, except for using ‘return await internalApi(name);’

The concept is simplified..we’re mocking up a realistic business scenario where we may want to retry an API call after an exception on the first try. If you look at the console output of the JSFiddle, variant 1 never retries the API call! What’s happening?
(variant 1)

(variant 2)

Back to Promises..
You can think of variant 1 as a promise returned without a .then(), and without a .catch(). If an error happens, it will bubble up higher in the program.
However variant 2 awaits the value (which implicitly is doing a .then() & .catch() )
Variant 1 is basically returning the promise, which would never trigger the catch block.
How might this happen in real-life code?
We saw this on a project where, because of the no-return-await rule, a developer was under the assumption that one should never write ‘return await’ in the code base. Ever.
As it turns out, in ESLint’s defense, they have this very example buried at the bottom of their documentation page (https://eslint.org/docs/latest/rules/no-return-await) here:

Take-aways
- If an ESLint rule is triggered that you’re not familiar with, read about it.
- Reading the details of ESLint rules can help you mature as a dev, and understand the pros/cons of rules (when to follow it, when to break it).
- Avoiding ‘return await’ is still good most of the time, for performance. But if you’re in a try/catch block, think twice. You might be skipping logic.