Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/fix-wrangler-signal-exit-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

Fix `wrangler` reporting exit code 0 when its child process is killed by a signal (e.g. OOM/SIGKILL)

Previously, if the underlying `wrangler` process was terminated by a signal rather than exiting normally, the CLI wrapper reported exit code 0, making CI pipelines and other automation believe the command succeeded. `wrangler` now reports a non-zero exit code and logs the signal in this case.
16 changes: 13 additions & 3 deletions packages/wrangler/bin/wrangler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ const path = require("path");
const MIN_NODE_VERSION = "22.0.0";
let wranglerProcess;

function resolveExitCode(code, signal) {
if (code !== null && code !== undefined) {
return code;
}
if (signal) {
console.error(`wrangler exited because it received signal ${signal}`);
}
return 1;
}

/**
* Executes ../wrangler-dist/cli.js
*/
Expand Down Expand Up @@ -33,9 +43,7 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
stdio: ["inherit", "inherit", "inherit", "ipc"],
}
)
.on("exit", (code) =>
process.exit(code === undefined || code === null ? 0 : code)
)
.on("exit", (code, signal) => process.exit(resolveExitCode(code, signal)))
.on("message", (message) => {
if (process.send) {
process.send(message);
Expand Down Expand Up @@ -89,3 +97,5 @@ if (module === require.main) {
wranglerProcess && wranglerProcess.kill();
});
}

module.exports = { resolveExitCode };
30 changes: 30 additions & 0 deletions packages/wrangler/src/__tests__/bin-wrangler-exit-code.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, it } from "vitest";
import { mockConsoleMethods } from "./helpers/mock-console";

// eslint-disable-next-line @typescript-eslint/no-require-imports -- bin/wrangler.js is a plain CommonJS script
const { resolveExitCode } = require("../../bin/wrangler.js");

describe("bin/wrangler.js resolveExitCode", () => {
const std = mockConsoleMethods();

it("passes through a normal numeric exit code", ({ expect }) => {
expect(resolveExitCode(0, null)).toBe(0);
expect(resolveExitCode(1, null)).toBe(1);
});

it("reports a non-zero exit code when killed by a signal", ({ expect }) => {
expect(resolveExitCode(null, "SIGKILL")).toBe(1);
expect(std.err).toContain("SIGKILL");
});

it("reports a non-zero exit code for SIGTERM", ({ expect }) => {
expect(resolveExitCode(null, "SIGTERM")).toBe(1);
expect(std.err).toContain("SIGTERM");
});

it("defaults to a non-zero exit code when code and signal are both missing", ({
expect,
}) => {
expect(resolveExitCode(undefined, null)).toBe(1);
});
});
Loading