diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index eaf99d34ea..64d3dda4ac 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -1939,7 +1939,7 @@ JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::JSValue options = JSC::jsUndefined(); JSC::JSObject* result - = JSC::ErrorInstance::create(globalObject, JSC::ErrorInstance::createStructure(vm, globalObject, globalObject->errorPrototype()), message, options); + = JSC::ErrorInstance::create(globalObject, globalObject->errorStructureWithErrorType(), message, options); auto clientData = WebCore::clientData(vm); @@ -1974,6 +1974,12 @@ JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::PropertyAttribute::DontDelete | 0); } + if (err.hostname.tag != BunStringTag::Empty) { + JSC::JSValue hostname = Bun::toJS(globalObject, err.hostname); + result->putDirect(vm, clientData->builtinNames().hostnamePublicName(), hostname, + JSC::PropertyAttribute::DontDelete | 0); + } + result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(err.errno_), JSC::PropertyAttribute::DontDelete | 0); diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 656e474477..d706b694fd 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -1711,6 +1711,7 @@ pub const SystemError = extern struct { message: String = String.empty, path: String = String.empty, syscall: String = String.empty, + hostname: String = String.empty, fd: bun.FileDescriptor = bun.toFD(-1), pub fn Maybe(comptime Result: type) type { @@ -1735,6 +1736,7 @@ pub const SystemError = extern struct { this.code.deref(); this.message.deref(); this.syscall.deref(); + this.hostname.deref(); } pub fn ref(this: *SystemError) void { @@ -1742,15 +1744,11 @@ pub const SystemError = extern struct { this.code.ref(); this.message.ref(); this.syscall.ref(); + this.hostname.ref(); } pub fn toErrorInstance(this: *const SystemError, global: *JSGlobalObject) JSValue { - defer { - this.path.deref(); - this.code.deref(); - this.message.deref(); - this.syscall.deref(); - } + defer this.deref(); return shim.cppFn("toErrorInstance", .{ this, global }); } @@ -1775,12 +1773,7 @@ pub const SystemError = extern struct { /// implementing follows this convention. It is exclusively used /// to match the error code that `node:os` throws. pub fn toErrorInstanceWithInfoObject(this: *const SystemError, global: *JSGlobalObject) JSValue { - defer { - this.path.deref(); - this.code.deref(); - this.message.deref(); - this.syscall.deref(); - } + defer this.deref(); return SystemError__toErrorInstanceWithInfoObject(this, global); } diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index 8c7b6802a5..488745edde 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -124,6 +124,7 @@ typedef struct SystemError { BunString message; BunString path; BunString syscall; + BunString hostname; int fd; } SystemError; diff --git a/src/deps/c_ares.zig b/src/deps/c_ares.zig index 4845addd6b..3360673ed0 100644 --- a/src/deps/c_ares.zig +++ b/src/deps/c_ares.zig @@ -1457,51 +1457,25 @@ pub const Error = enum(i32) { } pub fn reject(this: *Deferred, globalThis: *JSC.JSGlobalObject) void { - const error_value = globalThis.createErrorInstance("{s}", .{this.errno.label()}); + const system_error = blk: { + if (this.hostname) |hostname| { + break :blk JSC.SystemError{ + .errno = @intFromEnum(this.errno), + .code = bun.String.static(this.errno.code()), + .message = bun.String.createFormat("{s} {s} {s}", .{ this.syscall, @tagName(this.errno), hostname }) catch bun.outOfMemory(), + .syscall = bun.String.createUTF8(this.syscall), + .hostname = hostname.clone(), + }; + } else { + break :blk JSC.SystemError{ + .errno = @intFromEnum(this.errno), + .code = bun.String.static(this.errno.code()), + .syscall = bun.String.createUTF8(this.syscall), + }; + } + }; - error_value.put( - globalThis, - JSC.ZigString.static("name"), - bun.String.static("DNSException").toJS(globalThis), - ); - error_value.put( - globalThis, - JSC.ZigString.static("code"), - JSC.ZigString.init(this.errno.code()).toJS(globalThis), - ); - error_value.put( - globalThis, - JSC.ZigString.static("errno"), - JSC.jsNumber(@intFromEnum(this.errno)), - ); - - error_value.put( - globalThis, - JSC.ZigString.static("syscall"), - JSC.ZigString.init(this.syscall).toJS(globalThis), - ); - - if (this.hostname) |hostname| { - error_value.put( - globalThis, - JSC.ZigString.static("hostname"), - hostname.toJS(globalThis), - ); - - const utf8_hostname = hostname.toUTF8(bun.default_allocator); - defer utf8_hostname.deinit(); - - const message = std.mem.concat(bun.default_allocator, u8, &[_][]const u8{ this.syscall, " ", @tagName(this.errno), " ", utf8_hostname.slice() }) catch bun.outOfMemory(); - defer bun.default_allocator.free(message); - - error_value.put( - globalThis, - JSC.ZigString.static("message"), - JSC.ZigString.init(message).toJS(globalThis), - ); - } - - this.promise.reject(globalThis, error_value); + this.promise.reject(globalThis, system_error.toErrorInstance(globalThis)); this.deinit(); } @@ -1540,52 +1514,28 @@ pub const Error = enum(i32) { } pub fn toJS(this: Error, globalThis: *JSC.JSGlobalObject) JSC.JSValue { - const error_value = globalThis.createErrorInstance("{s}", .{this.label()}); - error_value.put( - globalThis, - JSC.ZigString.static("name"), - bun.String.static("DNSException").toJS(globalThis), - ); - error_value.put( - globalThis, - JSC.ZigString.static("code"), - JSC.ZigString.init(this.code()).toJS(globalThis), - ); - error_value.put( - globalThis, - JSC.ZigString.static("errno"), - JSC.jsNumber(@intFromEnum(this)), - ); - return error_value; + return (JSC.SystemError{ + .errno = @intFromEnum(this), + .code = bun.String.static(this.code()), + }).toErrorInstance(globalThis); } pub fn toJSWithSyscall(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8) JSC.JSValue { - const error_value = this.toJS(globalThis); - error_value.put( - globalThis, - JSC.ZigString.static("syscall"), - JSC.ZigString.static((syscall ++ "\x00")[0..syscall.len :0]).toJS(globalThis), - ); - return error_value; + return (JSC.SystemError{ + .errno = @intFromEnum(this), + .code = bun.String.static(this.code()), + .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), + }).toErrorInstance(globalThis); } pub fn toJSWithSyscallAndHostname(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8, hostname: []const u8) JSC.JSValue { - const error_value = this.toJSWithSyscall(globalThis, syscall); - error_value.put( - globalThis, - JSC.ZigString.static("hostname"), - JSC.ZigString.init(hostname).toJS(globalThis), - ); - - const message = std.mem.concat(bun.default_allocator, u8, &[_][]const u8{ syscall ++ " ", @tagName(this), " ", hostname }) catch bun.outOfMemory(); - defer bun.default_allocator.free(message); - - error_value.put( - globalThis, - JSC.ZigString.static("message"), - JSC.ZigString.init(message).toJS(globalThis), - ); - return error_value; + return (JSC.SystemError{ + .errno = @intFromEnum(this), + .code = bun.String.static(this.code()), + .message = bun.String.createFormat("{s} {s} {s}", .{ syscall, @tagName(this), hostname }) catch bun.outOfMemory(), + .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), + .hostname = bun.String.createUTF8(hostname), + }).toErrorInstance(globalThis); } pub fn initEAI(rc: i32) ?Error {