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.
|
||||
process.on("uncaughtException", (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
|
||||
// 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(err);
|
||||
}
|
||||
// And next, exit with a non-zero exit code.
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on("exit", () => { runtime.disconnectSync(); });
|
||||
|
|
|
@ -179,4 +179,3 @@ function stripEOL(data: string | Buffer): string {
|
|||
}
|
||||
return dataString;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const pulumi = require("../../../../../");
|
|||
assert.equal(pulumi.getProject(), "runtimeSettingsProject");
|
||||
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.requireNumber("A"), 42);
|
||||
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",
|
||||
stack: "runtimeSettingsStack",
|
||||
config: {
|
||||
"myBag:A": 42,
|
||||
"myBag:bbbb": "a string o' b's",
|
||||
"myBag:config:A": "42",
|
||||
"myBag:config:bbbb": "a string o' b's",
|
||||
},
|
||||
program: path.join(base, "010.runtime_settings"),
|
||||
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)) {
|
||||
|
|
Loading…
Reference in a new issue