wip error context

This commit is contained in:
2022-06-22 20:59:58 +03:00
parent 6aa4b01692
commit a4d5be6fab
3 changed files with 92 additions and 44 deletions

View File

@@ -28,16 +28,16 @@ pub fn main() !void {
const argv: []const [*:0]const u8 = os.argv;
const gpa = GeneralPurposeAllocator(.{});
const return_code = execute(gpa, argv[1..]) catch |err| {
try io.getStdErr().writeAll("uncaught error: {s}\n", @intToError(err));
os.exit(1);
};
const stderr = try io.getStdErr();
const stdout = try io.getStdOut();
const return_code = execute(gpa, stdout, stderr, argv[1..]);
os.exit(return_code);
}
fn execute(
allocator: Allocator,
stdout: anytype,
stderr: anytype,
argv: []const [*:0]const u8,
) u8 {
@@ -52,7 +52,7 @@ fn execute(
};
if (result.boolFlag("-h")) {
io.getStdOut().writeAll(usage) catch return 1;
stdout.writeAll(usage) catch return 1;
return 0;
}
@@ -66,62 +66,72 @@ fn execute(
const groupFname = result.argFlag("--group") orelse "./group";
const outFile = result.argFlag("--output") orelse "./db.turbo";
// to catch a specific file.OpenError, wait for
// to catch a specific file.OpenError, hold thumbs for
// https://github.com/ziglang/zig/issues/2473
var errc = ErrCtx{};
var passwdFile = fs.cwd().openFile(
passwdFname,
.{ .mode = .read_only },
) catch |err| {
stderr.print("Error opening {s}: {s}\n", .{ passwdFname, @errorName(err) }) catch {};
return 1;
};
) catch |err| return fail(errc.wrapf("open {s}", .{passwdFname}), stderr, err);
defer passwdFile.close();
var groupFile = fs.cwd().openFile(groupFname, .{ .mode = .read_only }) catch |err| {
stderr.print("Error opening {s}: {s}\n", .{ groupFname, @errorName(err) }) catch {};
return 1;
};
var groupFile = fs.cwd().openFile(groupFname, .{ .mode = .read_only }) catch |err|
return fail(errc.wrapf("open {s}", .{groupFname}), stderr, err);
defer groupFile.close();
var err_ctx = ErrCtx{};
var users = try User.fromReader(
var users = User.fromReader(
allocator,
&err_ctx,
&errc,
passwdFile.reader(),
);
errdefer {
stderr.print("ERROR", .{}) catch {};
var it = err_ctx.rev();
while (it.next()) |err|
stderr.print(": {s}", .{err}) catch {};
stderr.print("\n", .{}) catch {};
}
) catch |err| return fail(errc.wrap("read users"), stderr, err);
defer for (users) |*user| user.deinit(allocator);
defer allocator.free(users);
var groups = try Group.fromReader(allocator, groupFile.reader());
var groups = Group.fromReader(
allocator,
groupFile.reader(),
) catch |err| return fail(errc.wrap("read groups"), stderr, err);
defer for (groups) |*group| group.deinit(allocator);
defer allocator.free(groups);
var corpus = try Corpus.init(allocator, users, groups);
var corpus = Corpus.init(allocator, users, groups) catch |err|
return fail(errc.wrap("init corpus"), stderr, err);
defer corpus.deinit();
var db = try DB.fromCorpus(allocator, &corpus);
var db = DB.fromCorpus(allocator, &corpus) catch |err|
return fail(errc.wrap("construct db from corpus"), stderr, err);
defer db.deinit(allocator);
const fd = try os.open(outFile, os.O.WRONLY | os.O.TRUNC | os.O.CREAT, 0644);
const fd = os.open(outFile, os.O.WRONLY | os.O.TRUNC | os.O.CREAT, 0644) catch |err|
return fail(errc.wrapf("open for writing {s}", .{outFile}), stderr, err);
errdefer os.close(fd);
const len = try os.writev(fd, db.iov().constSlice());
try os.fsync(fd);
const len = os.writev(fd, db.iov().constSlice()) catch |err|
return fail(errc.wrapf("writev to {s}", .{outFile}), stderr, err);
os.fsync(fd) catch |err|
return fail(errc.wrapf("fsync {s}", .{outFile}), stderr, err);
os.close(fd);
try stderr.print("total {d} bytes. groups={d} users={d}\n", .{
stderr.print("total {d} bytes. groups={d} users={d}\n", .{
len,
users.len,
groups.len,
});
}) catch return 1;
return 0;
}
fn fail(errc: *ErrCtx, stderr: anytype, err: anytype) u8 {
stderr.print("ERROR {s}", .{@errorName(err)}) catch {};
var it = errc.rev();
while (it.next()) |msg|
stderr.print(": {s}", .{msg}) catch {};
stderr.print("\n", .{}) catch {};
return 1;
}
const testing = std.testing;
test "invalid argument" {
@@ -129,8 +139,12 @@ test "invalid argument" {
const args = &[_][*:0]const u8{"--invalid-argument"};
var stderr = ArrayList(u8).init(allocator);
defer stderr.deinit();
var stderrw = stderr.writer();
var stdout = ArrayList(u8).init(allocator);
defer stdout.deinit();
var stdoutw = stdout.writer();
const exit_code = execute(allocator, stderr.writer(), args[0..]);
const exit_code = execute(allocator, stdoutw, stderrw, args[0..]);
try testing.expectEqual(@as(u8, 1), exit_code);
try testing.expect(mem.startsWith(
u8,