Merge pull request #719 from pulumi/UnhandledPromiseRejection
Treat unhandled promise rejections as uncaught exceptions.
This commit is contained in:
commit
f449db974d
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
throw new Error("💥 goes the dynamite");
|
||||
throw new Error("💥 goes the dynamite");
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
new Promise((resolve, reject) => {
|
||||
reject(new Error("💥 goes the dynamite (as promised)"));
|
||||
});
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in a new issue