Exit with an error code in the face of unhandled errors (#495)
As part of fixing the exit bug recently, we accidentally made errors lead to zero exit codes. As a result, the Pulumi CLI thought the prgoram exited ordinarily, and proceeded to do its usual planning and deployment, rather than terminating abruptly. This is a byproduct of how Node's process.uncaughtException handler works. It hijacks and replaces all usual error logic, including the process.exit part. This change simply adds back the non-zero exit. I also added a test (and fixed one other that began failing afterwards), so that we can prevent regressions down the road.
This commit is contained in:
parent
2344f9e079
commit
cdb2c79e8e
|
@ -126,6 +126,7 @@ export function main(args: string[]): void {
|
||||||
|
|
||||||
// Set up the process unhandled exception handler and the program exit handler.
|
// Set up the process unhandled exception handler and the program exit handler.
|
||||||
process.on("uncaughtException", (err: Error) => {
|
process.on("uncaughtException", (err: Error) => {
|
||||||
|
// First, log the error.
|
||||||
if (err instanceof RunError) {
|
if (err instanceof RunError) {
|
||||||
// For errors that are subtypes of RunError, we will print the message without hitting the unhandled error
|
// For errors that are subtypes of RunError, we will print the message without hitting the unhandled error
|
||||||
// logic, which will dump all sorts of verbose spew like the origin source and stack trace.
|
// logic, which will dump all sorts of verbose spew like the origin source and stack trace.
|
||||||
|
@ -135,6 +136,8 @@ export function main(args: string[]): void {
|
||||||
console.log(`Running program '${program}' failed with an unhandled exception:`);
|
console.log(`Running program '${program}' failed with an unhandled exception:`);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
// And next, exit with a non-zero exit code.
|
||||||
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on("exit", () => { runtime.disconnectSync(); });
|
process.on("exit", () => { runtime.disconnectSync(); });
|
||||||
|
|
|
@ -179,4 +179,3 @@ function stripEOL(data: string | Buffer): string {
|
||||||
}
|
}
|
||||||
return dataString;
|
return dataString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ const pulumi = require("../../../../../");
|
||||||
assert.equal(pulumi.getProject(), "runtimeSettingsProject");
|
assert.equal(pulumi.getProject(), "runtimeSettingsProject");
|
||||||
assert.equal(pulumi.getStack(), "runtimeSettingsStack");
|
assert.equal(pulumi.getStack(), "runtimeSettingsStack");
|
||||||
|
|
||||||
const config = new pulumi.Config("myBag");
|
const config = new pulumi.Config("myBag:config");
|
||||||
assert.equal(config.getNumber("A"), 42);
|
assert.equal(config.getNumber("A"), 42);
|
||||||
assert.equal(config.requireNumber("A"), 42);
|
assert.equal(config.requireNumber("A"), 42);
|
||||||
assert.equal(config.get("bbbb"), "a string o' b's");
|
assert.equal(config.get("bbbb"), "a string o' b's");
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
throw new Error("💥 goes the dynamite");
|
|
@ -276,12 +276,18 @@ describe("rpc", () => {
|
||||||
project: "runtimeSettingsProject",
|
project: "runtimeSettingsProject",
|
||||||
stack: "runtimeSettingsStack",
|
stack: "runtimeSettingsStack",
|
||||||
config: {
|
config: {
|
||||||
"myBag:A": 42,
|
"myBag:config:A": "42",
|
||||||
"myBag:bbbb": "a string o' b's",
|
"myBag:config:bbbb": "a string o' b's",
|
||||||
},
|
},
|
||||||
program: path.join(base, "010.runtime_settings"),
|
program: path.join(base, "010.runtime_settings"),
|
||||||
expectResourceCount: 0,
|
expectResourceCount: 0,
|
||||||
},
|
},
|
||||||
|
// A program that throws an ordinary unhandled error.
|
||||||
|
"unhandled_error": {
|
||||||
|
program: path.join(base, "011.unhandled_error"),
|
||||||
|
expectResourceCount: 0,
|
||||||
|
expectError: "Program exited with non-zero exit code: 1",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const casename of Object.keys(cases)) {
|
for (const casename of Object.keys(cases)) {
|
||||||
|
|
Loading…
Reference in a new issue