Try/Catch always needed for await?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Try/Catch always needed for await?

Jordan Rome
My apologies if this has already been discussed but what is the "preferred" pattern for using await ? Since await, which runs on promises, will now throw if the promise is rejected (preventing execution of code after the await and killing the process in Node), is it neccesary to always be wrapping await in try/catch?

I don't wrap all my sync code (even when calling functions in an external dependency) in try/catch yet a lot of posts/articles I've seen written about await is that you should always wrap it in a try/catch. Is this because there is a lot of mis-use of reject, which, AFAIK, is supposed to contain an Error and is the async equivalent of throwing? Or maybe because you just don't know the source and length of the promise chain and therefore it's dangerous?

--
Best,

Jordan Rome

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Bergi
Jordan Rome schrieb:
> My apologies if this has already been discussed but what is the "preferred"
> pattern for using await ? Since await, which runs on promises, will now
> throw if the promise is rejected (preventing execution of code after the
> await and killing the process in Node), is it neccesary to always be
> wrapping await in try/catch?

No. Just like in synchronous code, you only wrap a part of your code in
try-catch if you actually want to *handle* an exception.

If you don't handle it, it will bubble as usual and reject the promise
returned by the `async function`. Let the caller deal with the
exceptions you can't handle - just like always.
Of course, in the top-level invocation it might be a good idea to use a
`catch` (or the `.catch()` method) to catch any exceptions and log them
to whereever you want if you don't want to get an unhandled rejection,
but those are usually exceptions you *don't expect* so you might not
need to deal with them at all.

- Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Alan Johnson
To perhaps clarify this point a bit, it is very important to `.catch()` and react appropriately at the ends of promise chains. If synchronous code fails for an unexpected reason, a visible crash will definitely happen. This is not the case for promises, because there’s no way for the runtime to know whether that promise is just some middle step in the chain, in which case you’d want to propagate rejection, rather than throw a synchronous exception. Having unexpected errors be silently swallowed is definitely a problematic property of promises, which you have to guard against.

It probably would be possible for the runtime to report crashes of promises that have no registered `.then()`. The only problem is, it’s totally possible the programmer is going to attach a `.then()` or `.catch()` later on to a promise that has already failed. Some promise libraries offer a `.done()` that has the semantics of “crash if this promise rejects”. But arguably, this should be the normal behavior, with an opt-out instead, so that it is assumed that you want rejected promises without any `.then()`s to throw synchronous exceptions. Something like a `.noFail()` could opt out

On Oct 14, 2016, at 09:30, Bergi <[hidden email]> wrote:

Jordan Rome schrieb:
My apologies if this has already been discussed but what is the "preferred"
pattern for using await ? Since await, which runs on promises, will now
throw if the promise is rejected (preventing execution of code after the
await and killing the process in Node), is it neccesary to always be
wrapping await in try/catch?

No. Just like in synchronous code, you only wrap a part of your code in try-catch if you actually want to *handle* an exception.

If you don't handle it, it will bubble as usual and reject the promise returned by the `async function`. Let the caller deal with the exceptions you can't handle - just like always.
Of course, in the top-level invocation it might be a good idea to use a `catch` (or the `.catch()` method) to catch any exceptions and log them to whereever you want if you don't want to get an unhandled rejection, but those are usually exceptions you *don't expect* so you might not need to deal with them at all.

- Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Andrea Giammarchi-2
Just one thought:

Of course, in the top-level invocation it might be a good idea to use a `catch`

after years of engine developers advocating "avoid try/catch as much as possible because it de-opts and slow down code and JIT and you name it", above suggestion doesn't really look like an "of course".

Using a proper `.catch()` within the async returned promise is probably the best approach.

Best Regards

On Fri, Oct 14, 2016 at 4:25 PM, Alan Johnson <[hidden email]> wrote:
To perhaps clarify this point a bit, it is very important to `.catch()` and react appropriately at the ends of promise chains. If synchronous code fails for an unexpected reason, a visible crash will definitely happen. This is not the case for promises, because there’s no way for the runtime to know whether that promise is just some middle step in the chain, in which case you’d want to propagate rejection, rather than throw a synchronous exception. Having unexpected errors be silently swallowed is definitely a problematic property of promises, which you have to guard against.

It probably would be possible for the runtime to report crashes of promises that have no registered `.then()`. The only problem is, it’s totally possible the programmer is going to attach a `.then()` or `.catch()` later on to a promise that has already failed. Some promise libraries offer a `.done()` that has the semantics of “crash if this promise rejects”. But arguably, this should be the normal behavior, with an opt-out instead, so that it is assumed that you want rejected promises without any `.then()`s to throw synchronous exceptions. Something like a `.noFail()` could opt out

On Oct 14, 2016, at 09:30, Bergi <[hidden email]> wrote:

Jordan Rome schrieb:
My apologies if this has already been discussed but what is the "preferred"
pattern for using await ? Since await, which runs on promises, will now
throw if the promise is rejected (preventing execution of code after the
await and killing the process in Node), is it neccesary to always be
wrapping await in try/catch?

No. Just like in synchronous code, you only wrap a part of your code in try-catch if you actually want to *handle* an exception.

If you don't handle it, it will bubble as usual and reject the promise returned by the `async function`. Let the caller deal with the exceptions you can't handle - just like always.
Of course, in the top-level invocation it might be a good idea to use a `catch` (or the `.catch()` method) to catch any exceptions and log them to whereever you want if you don't want to get an unhandled rejection, but those are usually exceptions you *don't expect* so you might not need to deal with them at all.

- Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Jordan Rome
In reply to this post by Alan Johnson

On Fri, Oct 14, 2016 at 11:25 AM, Alan Johnson <[hidden email]> wrote:
Having unexpected errors be silently swallowed is definitely a problematic property of promises, which you have to guard against.

I didn't think this was the case with await. If a promise rejection is not caught the await throws an exception and doesn't execute code below in the async function. Also, I believe Node is soon adding support for killing the process if a rejected Promise is not caught before it's garbage collected. If this is true why the importance of using try/catch with await, don't we want programmer errors to be noisy so we can fix them?

--
Best,

Jordan Rome
www.jordanrome.com

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Jordan Harband
When the await throws an exception that's not caught by a try/catch, the promise returned by the `async function` ends up rejected - and you have the identical scenario as a promise with an unhandled rejection.

node has been discussing adding "crash on garbage collection of an unhandled rejection", but the reason this is possible for them to add is because by the time something gets garbage collected, nothing in JS can possibly add a later catch handler - and this would cover promises and async functions *identically*.

In other words, async/await in no way whatsoever changes the discussion around unhandled promise rejections.

On Sat, Oct 15, 2016 at 11:09 AM, Jordan Rome <[hidden email]> wrote:

On Fri, Oct 14, 2016 at 11:25 AM, Alan Johnson <[hidden email]> wrote:
Having unexpected errors be silently swallowed is definitely a problematic property of promises, which you have to guard against.

I didn't think this was the case with await. If a promise rejection is not caught the await throws an exception and doesn't execute code below in the async function. Also, I believe Node is soon adding support for killing the process if a rejected Promise is not caught before it's garbage collected. If this is true why the importance of using try/catch with await, don't we want programmer errors to be noisy so we can fix them?

--
Best,

Jordan Rome
www.jordanrome.com

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Jordan Rome

On Sat, Oct 15, 2016 at 11:40 PM, Jordan Harband <[hidden email]> wrote:
When the await throws an exception that's not caught by a try/catch, the promise returned by the `async function` ends up rejected - and you have the identical scenario as a promise with an unhandled rejection.

Ah, that's the part I was missing and that 'await' is not allowed at the top level (for now). Thanks!

I think then my question really depends on the implementation of unhandled rejections? I see a lot of example code where 'catch' simply calls console.error (and/or logs an error to a backend). In chrome you get the 'Uncaught (in promise)' message in the console. I'm still confused as to why it's important to always try/catch (or even catch for promises) if you get an error message in the console (vs calling console.error manually). Do some engines still silently swallow these errors without any kind of notice?


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Marky Mark
On Sun, Oct 16, 2016, 5:32 AM Jordan Rome <[hidden email]> wrote:

I'm still confused as to why it's important to always try/catch (or even catch for promises) if you get an error message in the console (vs calling console.error manually).

You don't always have to catch promise errors. It's entirely optional and depends on your needs.Why do you think you always have to? But if you dont, your program will never know about the error or do anything to handle it.
--

mark

Sent while riding a hoverboard...
heyimmark.com :)


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Jordan Rome

On Sun, Oct 16, 2016 at 9:14 AM, Marky Mark <[hidden email]> wrote:
But if you dont, your program will never know about the error or do anything to handle it.

Perhaps this is where I'm confused. I'm under the impression that `catch` shouldn't be used anymore than try/catch does when you're writing synchronous code. I usually end up using try/catch only when there is a higher likelihood of programmer error (e.g. JSON.parse). If my program happens to throw, I don't just wrap that bit of code in another try/catch but I go and fix whatever was causing the throw (if fixable). I don't quite see how this changes with Promises or async code in general as I see a lot of folks adding catch and wrapping `await` in try/catch  -- claiming that it's "very important" to do this (quoting Alan above). Perhaps this is from a time when Promises were swallowing errors and not reporting unhandled rejections but it seems like browsers and node are fixing or have fixed this issue. So, if my Promise chain rejects and I have not caught it, I would just go in and fix whatever was throwing/rejecting (again, if fixable). 

--
Best,

Jordan Rome
www.jordanrome.com

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Try/Catch always needed for await?

Jordan Harband
Just because you get a message in your console that you have an unhandled rejection, doesn't mean your program can adapt to that as needed. Relying on that information is a last resort - it's the final safety net for you, the human, if you've failed to .catch all your promises at runtime (in your code).

On Mon, Oct 17, 2016 at 7:40 AM, Jordan Rome <[hidden email]> wrote:

On Sun, Oct 16, 2016 at 9:14 AM, Marky Mark <[hidden email]> wrote:
But if you dont, your program will never know about the error or do anything to handle it.

Perhaps this is where I'm confused. I'm under the impression that `catch` shouldn't be used anymore than try/catch does when you're writing synchronous code. I usually end up using try/catch only when there is a higher likelihood of programmer error (e.g. JSON.parse). If my program happens to throw, I don't just wrap that bit of code in another try/catch but I go and fix whatever was causing the throw (if fixable). I don't quite see how this changes with Promises or async code in general as I see a lot of folks adding catch and wrapping `await` in try/catch  -- claiming that it's "very important" to do this (quoting Alan above). Perhaps this is from a time when Promises were swallowing errors and not reporting unhandled rejections but it seems like browsers and node are fixing or have fixed this issue. So, if my Promise chain rejects and I have not caught it, I would just go in and fix whatever was throwing/rejecting (again, if fixable). 

--
Best,

Jordan Rome
www.jordanrome.com


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss