2 ms·
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 real
by robert_tweed 7y ago
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.