0

I moved to async/await from promises lately. However, I'm uncertain about the try...catch right flow. I have the following example:

const rp = require('request-promise');

const func2 = async () => {
    const response1 = await rp('http://nodejs.org/dist/index.json');
    if (response1) {
      return await rp('http://headers.jsontest.com'); // #opt 1: return a value
      // return rp('http://headers.jsontest.com'); // #opt 2: return a promise:
    }
}

(func1 = async () => {
  try {
    const response = await func2();
    console.log('Success!');
  } catch(e) {
    console.log('Failed!');
  }
})();

I was wondering if I should add try...catch to func2, but I came to conclusion it's already being handled in the try...catch of func1.

Is this code valid?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
wizard
  • 583
  • 2
  • 9
  • 26
  • 2
    Yes it's valid, but this is a highly opinionated and contextual question. It also depends on what exceptions you expect to see at `func2` and how you want to react to them. For example you might immediately want to handle an exception inside `func2` so that you could retry/recover and still return a valid response to the caller. – Luke Stoward Dec 15 '17 at 11:48
  • can you have the situation where `response1` is "falsey" but there's no error thrown? because in that case `response` would be `undefined` - is that valid? – Jaromanda X Dec 15 '17 at 11:51

1 Answers1

0

Is this code valid?

Yes. (In terms of the try/catch aspect, see "side note" below.)

I was wondering if I should add try...catch to func2, but I came to conclusion it's already being handled in the try...catch of func1.

Yes, it is. Just like with non-async functions, you only need the try/catch in func2 if you want to handle the error there (entirely, or partially and then (re)throwing). If you don't, allow it to propagate to the caller. Just ensure it's handled somewhere.


Side note: I'm assuming your func2 has a return in the case where response1 is a falsy value. If not, func2's promise's resolution value will be undefined in that case.


Side note 2: I'm guessing you've added the func1 = part there just to give yourself a name to refer to in the question and it's not in your real code. But in case it is: Unless you've declared it somewhere you haven't shown, in your example func1 is an implicit global. Recommend avoiding those. :-) More in my blog post: The Horror of Implicit Globals


Side note 3 (he does go on a bit, doesn't he?): If you're not using func1 anywhere else (just using it as a wrapper for convenient await use within it), if you want to, you can avoid a level of indentation by using the fact that async functions return promises:

(async () => {
  const response = await func2();
  console.log('Success!');
})().catch(e => {
  console.log('Failed!');
});

The up side is that it's a bit more concise. The downside is that it mixes metaphors. :-) That and the try/catch do exactly the same thing, it's purely a matter of how you prefer to write it, which is entirely up to you.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @LukeStoward: I just removed that parenthetical, it doesn't add anything. (In the *general* case, I disagree with you, but that opinion aspect doesn't need to come into the answer anyway, so... :-) ) – T.J. Crowder Dec 15 '17 at 11:54
  • I appreciate that, I guess it's a matter of whether you like to fail fast and fail loud or not. :) – Luke Stoward Dec 15 '17 at 12:00
  • @LukeStoward: You're failing fast and loud either way. – T.J. Crowder Dec 15 '17 at 12:03
  • @iT.J.Crowder for the **"side note"** if resolving the the site url will fail it will catch, otherwise it will get some value. I can't see when it will be `undefined`. P.S. This example is just for the sake of example. – wizard Dec 15 '17 at 12:09
  • @wizard: If the first line of your function will either throw (reject) or return a truthy value, then there's no need for the `if` at all. A throw (rejected promise) will exit `func2` prior to the `if`. – T.J. Crowder Dec 15 '17 at 12:21
  • @T.J.Crowder your'e right. however in which case it will return `undefined` ? – wizard Dec 15 '17 at 12:33
  • @wizard: If `response1` is a falsy value. Either it can be falsy, in which case that code returns (resolves) `undefined`, or it can't be falsy, in which case the `if` statement doesn't make sense. – T.J. Crowder Dec 15 '17 at 12:34