Skip to content

Commit

Permalink
system error changes
Browse files Browse the repository at this point in the history
  • Loading branch information
paperclover committed Jan 11, 2025
1 parent 17c80ad commit bd32776
Show file tree
Hide file tree
Showing 20 changed files with 455 additions and 162 deletions.
14 changes: 4 additions & 10 deletions src/bun.js/api/server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2709,18 +2709,14 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
file.pathlike.fd
else switch (bun.sys.open(file.pathlike.path.sliceZ(&file_buf), bun.O.RDONLY | bun.O.NONBLOCK | bun.O.CLOEXEC, 0)) {
.result => |_fd| _fd,
.err => |err| return this.runErrorHandler(err.withPath(file.pathlike.path.slice()).toSystemError().toErrorInstance(
globalThis,
)),
.err => |err| return this.runErrorHandler(err.withPath(file.pathlike.path.slice()).toJSC(globalThis)),
};

// stat only blocks if the target is a file descriptor
const stat: bun.Stat = switch (bun.sys.fstat(fd)) {
.result => |result| result,
.err => |err| {
this.runErrorHandler(err.withPathLike(file.pathlike).toSystemError().toErrorInstance(
globalThis,
));
this.runErrorHandler(err.withPathLike(file.pathlike).toJSC(globalThis));
if (auto_close) {
_ = bun.sys.close(fd);
}
Expand Down Expand Up @@ -2757,11 +2753,9 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
.errno = @as(bun.sys.Error.Int, @intCast(@intFromEnum(std.posix.E.INVAL))),
.syscall = .sendfile,
};
var sys = err.withPathLike(file.pathlike).toSystemError();
var sys = err.withPathLike(file.pathlike).toShellSystemError();
sys.message = bun.String.static("File must be regular or FIFO");
this.runErrorHandler(sys.toErrorInstance(
globalThis,
));
this.runErrorHandler(sys.toErrorInstance(globalThis));
return;
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/bun.js/node/node_fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5672,7 +5672,14 @@ pub const NodeFS = struct {
}

pub fn watch(_: *NodeFS, args: Arguments.Watch, comptime _: Flavor) Maybe(Return.Watch) {
return args.createFSWatcher();
return switch (args.createFSWatcher()) {
.result => |result| .{ .result = result.js_this },
.err => |err| .{ .err = .{
.errno = err.errno,
.syscall = err.syscall,
.path = if (err.path.len > 0) args.path.slice() else "",
} },
};
}

/// This function is `cpSync`, but only if you pass `{ recursive: ..., force: ..., errorOnExist: ..., mode: ... }'
Expand Down
7 changes: 1 addition & 6 deletions src/bun.js/node/node_fs_watcher.zig
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,7 @@ pub const FSWatcher = struct {
};
}

pub fn createFSWatcher(this: Arguments) JSC.Maybe(JSC.JSValue) {
return switch (FSWatcher.init(this)) {
.result => |result| .{ .result = result.js_this },
.err => |err| .{ .err = err },
};
}
pub const createFSWatcher = FSWatcher.init;
};

pub fn initJS(this: *FSWatcher, listener: JSC.JSValue) void {
Expand Down
2 changes: 0 additions & 2 deletions src/bun.js/node/types.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,6 @@ pub const Valid = struct {
switch (zig_str.len) {
0...bun.MAX_PATH_BYTES => return,
else => {
// TODO: should this be an EINVAL?
var system_error = bun.sys.Error.fromCode(.NAMETOOLONG, .open).withPath(zig_str.slice()).toSystemError();
system_error.syscall = bun.String.dead;
return ctx.throwValue(system_error.toErrorInstance(ctx));
Expand All @@ -1064,7 +1063,6 @@ pub const Valid = struct {
switch (len) {
0...bun.MAX_PATH_BYTES => return,
else => {
// TODO: should this be an EINVAL?
var system_error = bun.sys.Error.fromCode(.NAMETOOLONG, .open).toSystemError();
system_error.syscall = bun.String.dead;
return ctx.throwValue(system_error.toErrorInstance(ctx));
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/webcore/blob.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2756,7 +2756,7 @@ pub const Blob = struct {
pub fn throw(this: *CopyFileWindows, err: bun.sys.Error) void {
const globalThis = this.promise.strong.globalThis.?;
const promise = this.promise.swap();
const err_instance = err.toSystemError().toErrorInstance(globalThis);
const err_instance = err.toJS(globalThis);
var event_loop = this.event_loop;
event_loop.enter();
defer event_loop.exit();
Expand Down
19 changes: 5 additions & 14 deletions src/bundler/bundle_v2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13346,12 +13346,9 @@ pub const LinkerContext = struct {
},
)) {
.err => |err| {
var message = err.toSystemError().message.toUTF8(bun.default_allocator);
defer message.deinit();
c.log.addErrorFmt(null, Logger.Loc.Empty, bun.default_allocator, "{} writing sourcemap for chunk {}", .{
bun.fmt.quote(message.slice()),
try c.log.addSysError(bun.default_allocator, err, "writing sourcemap for chunk {}", .{
bun.fmt.quote(chunk.final_rel_path),
}) catch unreachable;
});
return error.WriteFailed;
},
.result => {},
Expand Down Expand Up @@ -13497,12 +13494,9 @@ pub const LinkerContext = struct {
},
)) {
.err => |err| {
var message = err.toSystemError().message.toUTF8(bun.default_allocator);
defer message.deinit();
c.log.addErrorFmt(null, Logger.Loc.Empty, bun.default_allocator, "{} writing chunk {}", .{
bun.fmt.quote(message.slice()),
try c.log.addSysError(bun.default_allocator, err, "writing chunk {}", .{
bun.fmt.quote(chunk.final_rel_path),
}) catch unreachable;
});
return error.WriteFailed;
},
.result => {},
Expand Down Expand Up @@ -13617,10 +13611,7 @@ pub const LinkerContext = struct {
},
)) {
.err => |err| {
const utf8 = err.toSystemError().message.toUTF8(bun.default_allocator);
defer utf8.deinit();
c.log.addErrorFmt(null, Logger.Loc.Empty, bun.default_allocator, "{} writing file {}", .{
bun.fmt.quote(utf8.slice()),
c.log.addSysError(bun.default_allocator, err, "writing file {}", .{
bun.fmt.quote(src.src_path.text),
}) catch unreachable;
return error.WriteFailed;
Expand Down
4 changes: 2 additions & 2 deletions src/cli/exec_command.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub const ExecCommand = struct {
const cwd = switch (bun.sys.getcwd(&buf)) {
.result => |p| p,
.err => |e| {
Output.prettyErrorln("<r><red>error<r>: Failed to run script <b>{s}<r> due to error <b>{s}<r>", .{ script, e.toSystemError() });
Output.err(e, "failed to run script <b>{s}<r>", .{script});
Global.exit(1);
},
};
Expand All @@ -40,7 +40,7 @@ pub const ExecCommand = struct {
const script_path = bun.path.join(parts, .auto);

const code = bun.shell.Interpreter.initAndRunFromSource(ctx, mini, script_path, script) catch |err| {
Output.prettyErrorln("<r><red>error<r>: Failed to run script <b>{s}<r> due to error <b>{s}<r>", .{ script_path, @errorName(err) });
Output.err(err, "failed to run script <b>{s}<r>", .{script_path});
Global.exit(1);
};

Expand Down
55 changes: 11 additions & 44 deletions src/install/install.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11352,10 +11352,7 @@ pub const PackageManager = struct {
switch (bun.sys.File.toSource(package_json_path, manager.allocator)) {
.result => |s| break :src s,
.err => |e| {
Output.prettyError(
"<r><red>error<r>: failed to read package.json: {}<r>\n",
.{e.withPath(package_json_path).toSystemError()},
);
Output.err(e, "failed to read {s}", .{bun.fmt.quote(package_json_path)});
Global.crash();
},
}
Expand Down Expand Up @@ -11766,10 +11763,7 @@ pub const PackageManager = struct {
switch (bun.sys.File.toSource(package_json_path, manager.allocator)) {
.result => |s| break :brk s,
.err => |e| {
Output.prettyError(
"<r><red>error<r>: failed to read package.json: {}<r>\n",
.{e.withPath(package_json_path).toSystemError()},
);
Output.err(e, "failed to read {s}", .{bun.fmt.quote(package_json_path)});
Global.crash();
},
}
Expand Down Expand Up @@ -11874,10 +11868,7 @@ pub const PackageManager = struct {
const cache_dir_path = switch (bun.sys.getFdPath(bun.toFD(cache_dir.fd), &buf2)) {
.result => |s| s,
.err => |e| {
Output.prettyError(
"<r><red>error<r>: failed to read from cache {}<r>\n",
.{e.toSystemError()},
);
Output.err(e, "failed to read from cache", .{});
Global.crash();
},
};
Expand All @@ -11888,10 +11879,7 @@ pub const PackageManager = struct {
};

const random_tempdir = bun.span(bun.fs.FileSystem.instance.tmpname("node_modules_tmp", buf2[0..], bun.fastRandom()) catch |e| {
Output.prettyError(
"<r><red>error<r>: failed to make tempdir {s}<r>\n",
.{@errorName(e)},
);
Output.err(e, "failed to make tempdir", .{});
Global.crash();
});

Expand All @@ -11902,10 +11890,7 @@ pub const PackageManager = struct {
// will `rename()` it out and back again.
const has_nested_node_modules = has_nested_node_modules: {
var new_folder_handle = std.fs.cwd().openDir(new_folder, .{}) catch |e| {
Output.prettyError(
"<r><red>error<r>: failed to open directory <b>{s}<r> {s}<r>\n",
.{ new_folder, @errorName(e) },
);
Output.err(e, "failed to open directory <b>{s}<r>", .{new_folder});
Global.crash();
};
defer new_folder_handle.close();
Expand All @@ -11922,10 +11907,7 @@ pub const PackageManager = struct {
};

const patch_tag_tmpname = bun.span(bun.fs.FileSystem.instance.tmpname("patch_tmp", buf3[0..], bun.fastRandom()) catch |e| {
Output.prettyError(
"<r><red>error<r>: failed to make tempdir {s}<r>\n",
.{@errorName(e)},
);
Output.err(e, "failed to make tempdir", .{});
Global.crash();
});

Expand All @@ -11943,10 +11925,7 @@ pub const PackageManager = struct {
break :has_bun_patch_tag null;
};
var new_folder_handle = std.fs.cwd().openDir(new_folder, .{}) catch |e| {
Output.prettyError(
"<r><red>error<r>: failed to open directory <b>{s}<r> {s}<r>\n",
.{ new_folder, @errorName(e) },
);
Output.err(e, "failed to open directory <b>{s}<r>", .{new_folder});
Global.crash();
};
defer new_folder_handle.close();
Expand Down Expand Up @@ -12097,20 +12076,14 @@ pub const PackageManager = struct {
)) {
.result => |fd| fd,
.err => |e| {
Output.prettyError(
"<r><red>error<r>: failed to open temp file {}<r>\n",
.{e.toSystemError()},
);
Output.err(e, "failed to open temp file", .{});
Global.crash();
},
};
defer _ = bun.sys.close(tmpfd);

if (bun.sys.File.writeAll(.{ .handle = tmpfd }, patchfile_contents.items).asErr()) |e| {
Output.prettyError(
"<r><red>error<r>: failed to write patch to temp file {}<r>\n",
.{e.toSystemError()},
);
Output.err(e, "failed to write patch to temp file", .{});
Global.crash();
}

Expand All @@ -12136,10 +12109,7 @@ pub const PackageManager = struct {
.path = .{ .string = bun.PathString.init(manager.options.patch_features.commit.patches_dir) },
};
if (nodefs.mkdirRecursive(args).asErr()) |e| {
Output.prettyError(
"<r><red>error<r>: failed to make patches dir {}<r>\n",
.{e.toSystemError()},
);
Output.err(e, "failed to make patches dir {}", .{bun.fmt.quote(args.path.slice())});
Global.crash();
}

Expand All @@ -12151,10 +12121,7 @@ pub const PackageManager = struct {
path_in_patches_dir,
.{ .move_fallback = true },
).asErr()) |e| {
Output.prettyError(
"<r><red>error<r>: failed renaming patch file to patches dir {}<r>\n",
.{e.toSystemError()},
);
Output.err(e, "failed renaming patch file to patches dir", .{});
Global.crash();
}

Expand Down
6 changes: 3 additions & 3 deletions src/install/lockfile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2508,7 +2508,7 @@ pub fn saveToDisk(this: *Lockfile, save_format: LoadResult.LockfileFormat, verbo

const file = switch (File.openat(std.fs.cwd(), tmpname, bun.O.CREAT | bun.O.WRONLY, 0o777)) {
.err => |err| {
Output.err(err, "failed to create temporary file to save lockfile\n{}", .{});
Output.err(err, "failed to create temporary file to save lockfile", .{});
Global.crash();
},
.result => |f| f,
Expand All @@ -2518,7 +2518,7 @@ pub fn saveToDisk(this: *Lockfile, save_format: LoadResult.LockfileFormat, verbo
.err => |e| {
file.close();
_ = bun.sys.unlink(tmpname);
Output.err(e, "failed to write lockfile\n{}", .{});
Output.err(e, "failed to write lockfile", .{});
Global.crash();
},
.result => {},
Expand All @@ -2534,7 +2534,7 @@ pub fn saveToDisk(this: *Lockfile, save_format: LoadResult.LockfileFormat, verbo
.err => |err| {
file.close();
_ = bun.sys.unlink(tmpname);
Output.err(err, "failed to change lockfile permissions\n{}", .{});
Output.err(err, "failed to change lockfile permissions", .{});
Global.crash();
},
.result => {},
Expand Down
6 changes: 3 additions & 3 deletions src/install/patch_install.zig
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ pub const PatchTask = struct {
)) {
.result => |txt| txt,
.err => |e| {
try log.addErrorFmtOpts(
try log.addSysError(
this.manager.allocator,
"failed to read patchfile: {}",
.{e.toSystemError()},
e,
"failed to read patchfile",
.{},
);
return;
Expand Down
15 changes: 15 additions & 0 deletions src/logger.zig
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,21 @@ pub const Log = struct {
});
}

// Use a bun.sys.Error's message in addition to some extra context.
pub fn addSysError(log: *Log, alloc: std.mem.Allocator, e: bun.sys.Error, comptime fmt: string, args: anytype) OOM!void {
const tag_name, const sys_errno = e.getErrorCodeTagName() orelse {
try log.addErrorFmt(null, Loc.Empty, alloc, fmt, args);
return;
};
try log.addErrorFmt(
null,
Loc.Empty,
alloc,
"{s}: " ++ fmt,
.{bun.sys.coreutils_error_map.get(sys_errno) orelse tag_name} ++ args,
);
}

pub fn addZigErrorWithNote(log: *Log, allocator: std.mem.Allocator, err: anyerror, comptime noteFmt: string, args: anytype) OOM!void {
@setCold(true);
log.errors += 1;
Expand Down
12 changes: 10 additions & 2 deletions src/output.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1063,12 +1063,20 @@ pub inline fn err(error_name: anytype, comptime fmt: []const u8, args: anytype)
const info = @typeInfo(T);

if (comptime T == bun.sys.Error or info == .Pointer and info.Pointer.child == bun.sys.Error) {
prettyErrorln("<r><red>error:<r><d>:<r> " ++ fmt, args ++ .{error_name});
const e: bun.sys.Error = error_name;
const tag_name, const sys_errno = e.getErrorCodeTagName() orelse {
err("unknown error", fmt, args);
return;
};
if (bun.sys.coreutils_error_map.get(sys_errno)) |label| {
prettyErrorln("<r><red>{s}<r><d>:<r> {s}: " ++ fmt ++ " <d>({s})<r>", .{ tag_name, label } ++ args ++ .{@tagName(e.syscall)});
} else {
prettyErrorln("<r><red>{s}<r><d>:<r> " ++ fmt ++ " <d>({s})<r>", .{tag_name} ++ args ++ .{@tagName(e.syscall)});
}
return;
}

const display_name, const is_comptime_name = display_name: {

// Zig string literals are of type *const [n:0]u8
// we assume that no one will pass this type from not using a string literal.
if (info == .Pointer and info.Pointer.size == .One and info.Pointer.is_const) {
Expand Down
Loading

0 comments on commit bd32776

Please sign in to comment.