mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
spawnSync shouldn't throw (#15561)
Co-authored-by: Meghan Denny <meghan@bun.sh>
This commit is contained in:
@@ -1766,13 +1766,13 @@ pub const Subprocess = struct {
|
||||
if (argv0 == null) {
|
||||
var path_buf: bun.PathBuffer = undefined;
|
||||
const resolved = Which.which(&path_buf, PATH, cwd, arg0.slice()) orelse {
|
||||
return globalThis.throwInvalidArguments("Executable not found in $PATH: \"{s}\"", .{arg0.slice()});
|
||||
return throwCommandNotFound(globalThis, arg0.slice());
|
||||
};
|
||||
argv0 = try allocator.dupeZ(u8, resolved);
|
||||
} else {
|
||||
var path_buf: bun.PathBuffer = undefined;
|
||||
const resolved = Which.which(&path_buf, PATH, cwd, bun.sliceTo(argv0.?, 0)) orelse {
|
||||
return globalThis.throwInvalidArguments("Executable not found in $PATH: \"{s}\"", .{arg0.slice()});
|
||||
return throwCommandNotFound(globalThis, arg0.slice());
|
||||
};
|
||||
argv0 = try allocator.dupeZ(u8, resolved);
|
||||
}
|
||||
@@ -2314,6 +2314,15 @@ pub const Subprocess = struct {
|
||||
return sync_value;
|
||||
}
|
||||
|
||||
fn throwCommandNotFound(globalThis: *JSC.JSGlobalObject, command: []const u8) bun.JSError {
|
||||
const message = bun.String.createFormat("Executable not found in $PATH: \"{s}\"", .{command}) catch bun.outOfMemory();
|
||||
defer message.deref();
|
||||
const err = message.toZigString().toErrorInstance(globalThis);
|
||||
err.putZigString(globalThis, JSC.ZigString.static("code"), JSC.ZigString.init("ENOENT").toJS(globalThis));
|
||||
err.putZigString(globalThis, JSC.ZigString.static("path"), JSC.ZigString.init(command).toJS(globalThis));
|
||||
return globalThis.throwValue(err);
|
||||
}
|
||||
|
||||
const node_cluster_binding = @import("./../../node/node_cluster_binding.zig");
|
||||
|
||||
pub fn handleIPCMessage(
|
||||
|
||||
@@ -4197,7 +4197,7 @@ pub const JSValue = enum(i64) {
|
||||
return cppFn("putRecord", .{ value, global, key, values_array, values_len });
|
||||
}
|
||||
|
||||
fn putZigString(value: JSValue, global: *JSGlobalObject, key: *const ZigString, result: JSC.JSValue) void {
|
||||
pub fn putZigString(value: JSValue, global: *JSGlobalObject, key: *const ZigString, result: JSC.JSValue) void {
|
||||
@import("./headers.zig").JSC__JSValue__put(value, global, key, result);
|
||||
}
|
||||
|
||||
|
||||
@@ -558,20 +558,27 @@ function spawnSync(file, args, options) {
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
stdout = null,
|
||||
stderr = null,
|
||||
success,
|
||||
exitCode,
|
||||
signalCode,
|
||||
} = Bun.spawnSync({
|
||||
cmd: options.args,
|
||||
env: options.env || undefined,
|
||||
cwd: options.cwd || undefined,
|
||||
stdio: bunStdio,
|
||||
windowsVerbatimArguments: options.windowsVerbatimArguments,
|
||||
windowsHide: options.windowsHide,
|
||||
});
|
||||
var error;
|
||||
try {
|
||||
var {
|
||||
stdout = null,
|
||||
stderr = null,
|
||||
success,
|
||||
exitCode,
|
||||
signalCode,
|
||||
} = Bun.spawnSync({
|
||||
cmd: options.args,
|
||||
env: options.env || undefined,
|
||||
cwd: options.cwd || undefined,
|
||||
stdio: bunStdio,
|
||||
windowsVerbatimArguments: options.windowsVerbatimArguments,
|
||||
windowsHide: options.windowsHide,
|
||||
});
|
||||
} catch (err) {
|
||||
error = err;
|
||||
stdout = null;
|
||||
stderr = null;
|
||||
}
|
||||
|
||||
const result = {
|
||||
signal: signalCode ?? null,
|
||||
@@ -580,6 +587,10 @@ function spawnSync(file, args, options) {
|
||||
output: [null, stdout, stderr],
|
||||
};
|
||||
|
||||
if (error) {
|
||||
result.error = error;
|
||||
}
|
||||
|
||||
if (stdout && encoding && encoding !== "buffer") {
|
||||
result.output[1] = result.output[1]?.toString(encoding);
|
||||
}
|
||||
@@ -591,8 +602,11 @@ function spawnSync(file, args, options) {
|
||||
result.stdout = result.output[1];
|
||||
result.stderr = result.output[2];
|
||||
|
||||
if (!success) {
|
||||
if (!success && error == null) {
|
||||
result.error = new SystemError(result.output[2], options.file, "spawnSync", -1, result.status);
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
result.error.spawnargs = ArrayPrototypeSlice.$call(options.args, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -454,3 +454,13 @@ it.if(!isWindows)("spawnSync correctly reports signal codes", () => {
|
||||
|
||||
expect(signal).toBe("SIGTRAP");
|
||||
});
|
||||
|
||||
it("spawnSync(does-not-exist)", () => {
|
||||
const x = spawnSync("does-not-exist");
|
||||
expect(x.error?.code).toEqual("ENOENT");
|
||||
expect(x.error.path).toEqual("does-not-exist");
|
||||
expect(x.signal).toEqual(null);
|
||||
expect(x.output).toEqual([null, null, null]);
|
||||
expect(x.stdout).toEqual(null);
|
||||
expect(x.stderr).toEqual(null);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user