Drain the message queue before exiting (#498)

This change remembers that we failed due to an uncaught exception,
and defers the process.exit(1) until we actually reach the process's
exit event.  This ensures that we drain the message queue before
exiting, which ensures that outbound messages actually reach their
destination.
This commit is contained in:
Joe Duffy 2017-10-30 11:48:54 -07:00 committed by GitHub
parent bd5e54d63e
commit 0383c24087
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 11 deletions

View file

@ -125,6 +125,7 @@ export function main(args: string[]): void {
process.argv = [ process.argv[0], process.argv[1], ...programArgs ];
// Set up the process unhandled exception handler and the program exit handler.
let uncaught: Error | undefined;
process.on("uncaughtException", (err: Error) => {
// First, log the error.
if (err instanceof RunError) {
@ -133,14 +134,22 @@ export function main(args: string[]): void {
log.error(err.message);
}
else {
console.log(`Running program '${program}' failed with an unhandled exception:`);
console.log(err);
log.error(`Running program '${program}' failed with an unhandled exception:`);
log.error(err.toString());
}
// And next, exit with a non-zero exit code.
process.exit(1);
// Remember that we failed with an error. Don't quit just yet so we have a chance to drain the message loop.
uncaught = err;
});
process.on("exit", () => { runtime.disconnectSync(); });
process.on("exit", (code: number) => {
runtime.disconnectSync();
// If we don't already have an exit code, and we had an unhandled error, exit with a non-success.
if (code === 0 && uncaught) {
process.exit(1);
}
});
// Now go ahead and execute the code. The process will remain alive until the message loop empties.
log.debug(`Running program '${program}' in pwd '${process.cwd()}' w/ args: ${programArgs}`);

View file

@ -101,13 +101,18 @@ export function disconnect(): void {
*/
export function disconnectSync(): void {
// Otherwise, actually perform the close activities.
if (options.monitor) {
(<any>options.monitor).close();
(<any>options).monitor = null;
try {
if (options.monitor) {
(<any>options.monitor).close();
(<any>options).monitor = null;
}
if (options.engine) {
(<any>options.engine).close();
(<any>options).engine = null;
}
}
if (options.engine) {
(<any>options.engine).close();
(<any>options).engine = null;
catch (err) {
// ignore all failures to avoid crashes during exit.
}
}