From 87c8fbd7832dcdf101f0aa6abb3eb8962ddf1e72 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Mon, 23 Jun 2025 20:26:28 -0700 Subject: [PATCH] use type safety to ensure SystemError errno consistency --- src/bun.js/api/bun/dns_resolver.zig | 4 ++-- src/bun.js/api/bun/socket.zig | 4 ++-- src/bun.js/api/bun/subprocess.zig | 6 +++--- src/bun.js/api/bun/udp_socket.zig | 2 +- src/bun.js/bindings/SystemError.zig | 4 ++-- src/bun.js/bindings/ZigException.zig | 2 +- src/bun.js/bindings/bindings.cpp | 6 +++--- src/bun.js/bindings/headers-handwritten.h | 4 ++-- src/bun.js/node/node_os.zig | 8 ++++---- src/deps/c_ares.zig | 8 ++++---- src/sys.zig | 4 ++-- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig index 4fe7437c67..21ad0890cf 100644 --- a/src/bun.js/api/bun/dns_resolver.zig +++ b/src/bun.js/api/bun/dns_resolver.zig @@ -2414,7 +2414,7 @@ pub const DNSResolver = struct { .result => |result| return result, .err => |err| { const system_error = JSC.SystemError{ - .errno = -1, + .errno = @intFromEnum(bun.sys.SystemErrno.EPERM), .code = bun.String.static(err.code()), .message = bun.String.static(err.label()), }; @@ -3120,7 +3120,7 @@ pub const DNSResolver = struct { defer syscall.deref(); const system_error = JSC.SystemError{ - .errno = -1, + .errno = @intFromEnum(bun.sys.SystemErrno.EPERM), .code = bun.String.static(err.code()), .message = bun.String.static(err.label()), .syscall = syscall, diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index 1d6551f486..c2cdce2eba 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -307,7 +307,7 @@ pub fn NewSocket(comptime ssl: bool) type { } bun.assert(errno >= 0); - var errno_: c_int = if (errno == @intFromEnum(bun.sys.SystemErrno.ENOENT)) @intFromEnum(bun.sys.SystemErrno.ENOENT) else @intFromEnum(bun.sys.SystemErrno.ECONNREFUSED); + var errno_: c_uint = if (errno == @intFromEnum(bun.sys.SystemErrno.ENOENT)) @intFromEnum(bun.sys.SystemErrno.ENOENT) else @intFromEnum(bun.sys.SystemErrno.ECONNREFUSED); const code_ = if (errno == @intFromEnum(bun.sys.SystemErrno.ENOENT)) bun.String.static("ENOENT") else bun.String.static("ECONNREFUSED"); if (Environment.isWindows and errno_ == @intFromEnum(bun.sys.SystemErrno.ENOENT)) errno_ = @intFromEnum(bun.sys.SystemErrno.UV_ENOENT); if (Environment.isWindows and errno_ == @intFromEnum(bun.sys.SystemErrno.ECONNREFUSED)) errno_ = @intFromEnum(bun.sys.SystemErrno.UV_ECONNREFUSED); @@ -315,7 +315,7 @@ pub fn NewSocket(comptime ssl: bool) type { const callback = handlers.onConnectError; const globalObject = handlers.globalObject; const err = JSC.SystemError{ - .errno = -errno_, + .errno = errno_, .message = bun.String.static("Failed to connect"), .syscall = bun.String.static("connect"), .code = code_, diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 428ac48320..96ddca4c7a 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -2297,7 +2297,7 @@ pub fn spawnMaybeSync( else ""; var systemerror = bun.sys.Error.fromCode(if (err == error.EMFILE) .MFILE else .NFILE, .posix_spawn).withPath(display_path).toSystemError(); - systemerror.errno = if (err == error.EMFILE) -bun.sys.UV_E.MFILE else -bun.sys.UV_E.NFILE; + systemerror.errno = if (err == error.EMFILE) bun.sys.UV_E.MFILE else bun.sys.UV_E.NFILE; return globalThis.throwValue(systemerror.toErrorInstance(globalThis)); }, else => { @@ -2315,7 +2315,7 @@ pub fn spawnMaybeSync( ""; if (display_path.len > 0) { var systemerror = err.withPath(display_path).toSystemError(); - if (errno == .NOENT) systemerror.errno = -bun.sys.UV_E.NOENT; + if (errno == .NOENT) systemerror.errno = bun.sys.UV_E.NOENT; return globalThis.throwValue(systemerror.toErrorInstance(globalThis)); } }, @@ -2624,7 +2624,7 @@ fn throwCommandNotFound(globalThis: *JSC.JSGlobalObject, command: []const u8) bu const err = JSC.SystemError{ .message = bun.String.createFormat("Executable not found in $PATH: \"{s}\"", .{command}) catch bun.outOfMemory(), .code = bun.String.static("ENOENT"), - .errno = -bun.sys.UV_E.NOENT, + .errno = bun.sys.UV_E.NOENT, .path = bun.String.createUTF8(command), }; return globalThis.throwValue(err.toErrorInstance(globalThis)); diff --git a/src/bun.js/api/bun/udp_socket.zig b/src/bun.js/api/bun/udp_socket.zig index d6ae1e3765..237256b93b 100644 --- a/src/bun.js/api/bun/udp_socket.zig +++ b/src/bun.js/api/bun/udp_socket.zig @@ -334,7 +334,7 @@ pub const UDPSocket = struct { if (err != 0) { const code = @tagName(bun.sys.SystemErrno.init(@as(c_int, @intCast(err))).?); const sys_err = JSC.SystemError{ - .errno = err, + .errno = @intCast(err), .code = bun.String.static(code), .message = bun.String.createFormat("bind {s} {s}", .{ code, config.hostname }) catch bun.outOfMemory(), }; diff --git a/src/bun.js/bindings/SystemError.zig b/src/bun.js/bindings/SystemError.zig index 484ed54489..cf43c13d6c 100644 --- a/src/bun.js/bindings/SystemError.zig +++ b/src/bun.js/bindings/SystemError.zig @@ -6,7 +6,7 @@ const JSValue = JSC.JSValue; const JSGlobalObject = JSC.JSGlobalObject; pub const SystemError = extern struct { - errno: c_int = 0, + errno: c_uint = 0, /// label for errno code: String = .empty, message: String = .empty, @@ -29,7 +29,7 @@ pub const SystemError = extern struct { pub fn getErrno(this: *const SystemError) bun.sys.E { // The inverse in bun.sys.Error.toSystemError() - return @enumFromInt(this.errno * -1); + return @enumFromInt(this.errno); } pub fn deref(this: *const SystemError) void { diff --git a/src/bun.js/bindings/ZigException.zig b/src/bun.js/bindings/ZigException.zig index bdd38fb2db..b5193ff340 100644 --- a/src/bun.js/bindings/ZigException.zig +++ b/src/bun.js/bindings/ZigException.zig @@ -19,7 +19,7 @@ pub const ZigException = extern struct { runtime_type: JSRuntimeType, /// SystemError only - errno: c_int = 0, + errno: c_uint = 0, /// SystemError only syscall: String = String.empty, /// SystemError only diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 540c82d348..65c8fa5b64 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -2201,7 +2201,7 @@ JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::J result->putDirect(vm, names.hostnamePublicName(), hostname, JSC::PropertyAttribute::DontDelete | 0); } - result->putDirect(vm, names.errnoPublicName(), JSC::JSValue(err.errno_), JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, names.errnoPublicName(), JSC::JSValue(-(int)err.errno_), JSC::PropertyAttribute::DontDelete | 0); RETURN_IF_EXCEPTION(scope, {}); scope.release(); @@ -2244,8 +2244,8 @@ JSC::EncodedJSValue SystemError__toErrorInstanceWithInfoObject(const SystemError info->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, codeString), JSC::PropertyAttribute::DontDelete | 0); info->putDirect(vm, vm.propertyNames->message, jsString(vm, messageString), JSC::PropertyAttribute::DontDelete | 0); - info->putDirect(vm, clientData->builtinNames().errnoPublicName(), jsNumber(err.errno_), JSC::PropertyAttribute::DontDelete | 0); - result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(err.errno_), JSC::PropertyAttribute::DontDelete | 0); + info->putDirect(vm, clientData->builtinNames().errnoPublicName(), jsNumber(-(int)err.errno_), JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(-(int)err.errno_), JSC::PropertyAttribute::DontDelete | 0); RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::JSValue(result))); } diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index 7a2a364ef0..dc3adaec55 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -128,7 +128,7 @@ typedef struct ErrorableResolvedSource { } ErrorableResolvedSource; typedef struct SystemError { - int errno_; + unsigned int errno_; BunString code; BunString message; BunString path; @@ -195,7 +195,7 @@ typedef struct ZigStackTrace { typedef struct ZigException { unsigned char type; uint16_t runtime_type; - int errno_; + unsigned int errno_; BunString syscall; BunString system_code; BunString path; diff --git a/src/bun.js/node/node_os.zig b/src/bun.js/node/node_os.zig index 6a4b9aa8f5..659ffb4039 100644 --- a/src/bun.js/node/node_os.zig +++ b/src/bun.js/node/node_os.zig @@ -302,7 +302,7 @@ pub fn getPriority(global: *JSC.JSGlobalObject, pid: i32) bun.JSError!i32 { .message = bun.String.static("no such process"), .code = bun.String.static("ESRCH"), .errno = comptime switch (bun.Environment.os) { - else => -@as(c_int, @intFromEnum(std.posix.E.SRCH)), + else => @intFromEnum(std.posix.E.SRCH), .windows => libuv.UV_ESRCH, }, .syscall = bun.String.static("uv_os_getpriority"), @@ -825,7 +825,7 @@ pub fn setPriority1(global: *JSC.JSGlobalObject, pid: i32, priority: i32) !void .message = bun.String.static("no such process"), .code = bun.String.static("ESRCH"), .errno = comptime switch (bun.Environment.os) { - else => -@as(c_int, @intFromEnum(std.posix.E.SRCH)), + else => @intFromEnum(std.posix.E.SRCH), .windows => libuv.UV_ESRCH, }, .syscall = bun.String.static("uv_os_getpriority"), @@ -837,7 +837,7 @@ pub fn setPriority1(global: *JSC.JSGlobalObject, pid: i32, priority: i32) !void .message = bun.String.static("permission denied"), .code = bun.String.static("EACCES"), .errno = comptime switch (bun.Environment.os) { - else => -@as(c_int, @intFromEnum(std.posix.E.ACCES)), + else => @intFromEnum(std.posix.E.ACCES), .windows => libuv.UV_EACCES, }, .syscall = bun.String.static("uv_os_getpriority"), @@ -849,7 +849,7 @@ pub fn setPriority1(global: *JSC.JSGlobalObject, pid: i32, priority: i32) !void .message = bun.String.static("operation not permitted"), .code = bun.String.static("EPERM"), .errno = comptime switch (bun.Environment.os) { - else => -@as(c_int, @intFromEnum(std.posix.E.SRCH)), + else => @intFromEnum(std.posix.E.SRCH), .windows => libuv.UV_ESRCH, }, .syscall = bun.String.static("uv_os_getpriority"), diff --git a/src/deps/c_ares.zig b/src/deps/c_ares.zig index 44dbc53791..1e4a10424c 100644 --- a/src/deps/c_ares.zig +++ b/src/deps/c_ares.zig @@ -1695,7 +1695,7 @@ pub const Error = enum(i32) { pub fn reject(this: *Deferred, globalThis: *JSC.JSGlobalObject) void { const system_error = JSC.SystemError{ - .errno = @intFromEnum(this.errno), + .errno = @intCast(@intFromEnum(this.errno)), .code = bun.String.static(this.errno.code()), .message = if (this.hostname) |hostname| bun.String.createFormat("{s} {s} {s}", .{ this.syscall, this.errno.code()[4..], hostname }) catch bun.outOfMemory() else bun.String.empty, .syscall = bun.String.createUTF8(this.syscall), @@ -1747,7 +1747,7 @@ pub const Error = enum(i32) { pub fn toJS(this: Error, globalThis: *JSC.JSGlobalObject) JSC.JSValue { const instance = (JSC.SystemError{ - .errno = @intFromEnum(this), + .errno = @intCast(@intFromEnum(this)), .code = bun.String.static(this.code()), }).toErrorInstance(globalThis); instance.put(globalThis, "name", bun.String.static("DNSException").toJS(globalThis)); @@ -1756,7 +1756,7 @@ pub const Error = enum(i32) { pub fn toJSWithSyscall(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8) JSC.JSValue { const instance = (JSC.SystemError{ - .errno = @intFromEnum(this), + .errno = @intCast(@intFromEnum(this)), .code = bun.String.static(this.code()), .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), }).toErrorInstance(globalThis); @@ -1766,7 +1766,7 @@ pub const Error = enum(i32) { pub fn toJSWithSyscallAndHostname(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8, hostname: []const u8) JSC.JSValue { const instance = (JSC.SystemError{ - .errno = @intFromEnum(this), + .errno = @intCast(@intFromEnum(this)), .code = bun.String.static(this.code()), .message = bun.String.createFormat("{s} {s} {s}", .{ syscall, this.code()[4..], hostname }) catch bun.outOfMemory(), .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), diff --git a/src/sys.zig b/src/sys.zig index 6d8e1e71c4..8b1bae52ce 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -534,7 +534,7 @@ pub const Error = struct { pub fn toShellSystemError(this: Error) SystemError { @setEvalBranchQuota(1_000_000); var err = SystemError{ - .errno = @as(c_int, this.errno) * -1, + .errno = this.errno, .syscall = bun.String.static(@tagName(this.syscall)), }; @@ -569,7 +569,7 @@ pub const Error = struct { /// Use this whenever the error will be sent to JavaScript instead of the shell variant above. pub fn toSystemError(this: Error) SystemError { var err = SystemError{ - .errno = -%@as(c_int, this.errno), + .errno = this.errno, .syscall = bun.String.static(@tagName(this.syscall)), };