News for hackers. Stuff that matters.
Re:V8 adds support for top-level await by olalonde on Wednesday September 25, 2019 @07:20AM (#21069623)
> While this is 100% correct, if the main function has returned then the process was going to end anyway (assuming there isn't additional code after the call to main).

That's not necessarily the case (or maybe poorly worded), e.g.:

    async function main() {
      // code
      setInterval(() => console.log('hey'), 1000)
    }
    main()
In real life, it would probably be a HTTP server holding up the process. It's true that you likely want to crash hard if you have unhandled error during server initialization but I would still catch the error because Node.js will otherwise print a bunch of ugly "UnhandledPromiseRejectionWarning" messages. E.g.:

    main().catch(err => {
      console.error(err);
      process.exit(1);
    });
With top level async landing in v8, I guess Node.js will eventually stop printing those warning messages.
Re:V8 adds support for top-level await by robert_tweed on Wednesday September 25, 2019 @09:35AM (#21070610)
You raise an interesting point. If you are doing anything non-trivial, you should definitely be using a main loop and catching errors inside that loop. You really don't want to rely on the default behaviour of orphaned timers, because that can get interesting.

I did a quick test just to see how bad things might get if you were to rely on orphaned timers like this. The important thing to keep in mind is that each of those timers is effectively its own thread, which can throw errors and terminate itself. But if those are orphaned outside of a runloop that can handle those errors, they will not be caught by the catch outside of main (which only catches errors thrown in the "main thread"). Rather, they become top-level, uncaught exceptions, which also terminate the process.

Here's an example illustrating what happens:

    async function main() {
        setTimeout( () => console.log( 'Hello' ), 3000 );
        setTimeout( function() { throw new Error('error 1'); }, 1000 );
        setTimeout( function() { throw new Error('error 2'); }, 2000 );
        throw new Error('oops');
    }

    main().catch( x => console.error( x ) );
The result here is that `oops` is displayed (the caught error from the "main thread") and then `error 1` is displayed, but the process is then immediately terminated. Neither `error 2` nor `Hello` are displayed.

Note that I use the term "thread" loosely, in the "green thread" sense. Hopefully the meaning is clear.