Merge pull request #719 from pulumi/UnhandledPromiseRejection

Treat unhandled promise rejections as uncaught exceptions.
This commit is contained in:
Pat Gavlin 2017-12-13 17:51:44 -08:00 committed by GitHub
commit f449db974d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 15 additions and 21 deletions

View file

@ -118,9 +118,9 @@ export function main(args: string[]): void {
const programArgs: string[] = argv._.slice(1);
process.argv = [ process.argv[0], process.argv[1], ...programArgs ];
// Set up the process unhandled exception handler and the program exit handler.
// Set up the process uncaught exception, unhandled rejection, and program exit handlers.
let uncaught: Error | undefined;
process.on("uncaughtException", (err: Error) => {
const uncaughtHandler = (err: Error) => {
// First, log the error.
if (err instanceof RunError) {
// For errors that are subtypes of RunError, we will print the message without hitting the unhandled error
@ -134,7 +134,9 @@ export function main(args: string[]): void {
// 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("uncaughtException", uncaughtHandler);
process.on("unhandledRejection", uncaughtHandler);
process.on("exit", (code: number) => {
runtime.disconnectSync();

View file

@ -22,10 +22,6 @@ let leakDetectorScheduled: boolean = false;
* leakCandidates tracks the list of potential leak candidates.
*/
const leakCandidates: Set<Promise<any>> = new Set<Promise<any>>();
/**
* unhandledHandlerScheduled is true when the unhandled promise detector is scheduled for this process.
*/
let unhandledHandlerScheduled: boolean = false;
function promiseDebugString(p: Promise<any>): string {
return `CONTEXT: ${(<any>p)._debugCtx}\n` +
@ -41,19 +37,6 @@ export function debuggablePromise<T>(p: Promise<T>, ctx?: any): Promise<T> {
(<any>p)._debugCtx = ctx;
(<any>p)._debugStackTrace = new Error().stack;
// If the unhandled handler isn't active yet, schedule it.
if (!unhandledHandlerScheduled) {
process.on("unhandledRejection", (reason, innerPromise) => {
if (!log.hasErrors()) {
console.error("Unhandled promise rejection:");
console.error(reason);
console.error(reason.stack);
console.error(promiseDebugString(innerPromise));
}
});
unhandledHandlerScheduled = true;
}
if (debugPromiseLeaks) {
// Setup leak detection.
if (!leakDetectorScheduled) {

View file

@ -1 +1 @@
throw new Error("💥 goes the dynamite");
throw new Error("💥 goes the dynamite");

View file

@ -0,0 +1,3 @@
new Promise((resolve, reject) => {
reject(new Error("💥 goes the dynamite (as promised)"));
});

View file

@ -310,6 +310,12 @@ describe("rpc", () => {
return { urn: makeUrn(t, name), id: undefined, props: res };
},
},
// A program that contains an unhandled promise rejection.
"unhandled_promise_rejection": {
program: path.join(base, "013.unhandled_promise_rejection"),
expectResourceCount: 0,
expectError: "Program exited with non-zero exit code: 1",
},
};
for (const casename of Object.keys(cases)) {