const std = @import("std");
const expect = std.testing.expect;
fn perform() void {
errdefer |err| {
std.debug.warn("an error occurred: {}\n", @errorName(err));
std.process.exit(1);
}
_ = try std.math.add(u8, 255, 1);
}
pub fn main() void {
perform();
}
Expected: compiles successfully
Actual:
./test2.zig:9:9: error: expected type 'void', found 'std.math.error:340:43'
_ = try std.math.add(u8, 255, 1);
^
This would be really nice. Much better than having to do this:
fn main2() !void {
// the real code
}
fn main() u8 {
main2() catch |err| {
std.debug.warn("{}\n", .{err});
return 1;
};
return 0;
}
Would you also be allowed to call return in the errdefer block?
Would you also be allowed to call
returnin theerrdeferblock?
That's a good question. I worry that would start to get too edge-casey and complicated to reason about. For example, will the other defers above it run or not if you do that? Regardless of what Zig does, someone reading such code for the first time will not know the answer to this question.
You're right, it is pretty hard to think about. Maybe this pattern is mostly useful for the main function, in which case your example with std.process.exit would suffice.
using errdefer for error handling seems like an antipattern. The main2 example dbandstra posted above more effectively communicates intent. errdefer is meant to be used to clean up while returning an error, not prevent returning an error.
it is currently a compile error to return from a defer, and it should stay that way. otherwise, you get into strange scenarios where your code executes multiple return statements that override each other.
Most helpful comment
using
errdeferfor error handling seems like an antipattern. Themain2example dbandstra posted above more effectively communicates intent.errdeferis meant to be used to clean up while returning an error, not prevent returning an error.it is currently a compile error to return from a defer, and it should stay that way. otherwise, you get into strange scenarios where your code executes multiple return statements that override each other.