Add Zig Error Handling Example
This commit is contained in:
parent
f5517fd441
commit
e394029a24
2
zig-error-handling/.gitignore
vendored
Normal file
2
zig-error-handling/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
zig-out/
|
||||
.zig-cache/
|
26
zig-error-handling/build.zig
Normal file
26
zig-error-handling/build.zig
Normal file
@ -0,0 +1,26 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "zig-error-handling",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = b.host,
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_exe = b.addRunArtifact(exe);
|
||||
const run_step = b.step("run", "Run the application");
|
||||
|
||||
run_step.dependOn(&run_exe.step);
|
||||
|
||||
const unit_tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = b.host,
|
||||
});
|
||||
|
||||
const test_step = b.step("test", "Run unit tests");
|
||||
const run_unit_tests = b.addRunArtifact(unit_tests);
|
||||
|
||||
test_step.dependOn(&run_unit_tests.step);
|
||||
}
|
77
zig-error-handling/src/main.zig
Normal file
77
zig-error-handling/src/main.zig
Normal file
@ -0,0 +1,77 @@
|
||||
const std = @import("std");
|
||||
|
||||
const AddNumbersError = error{
|
||||
InequalLengths,
|
||||
GuardOverflow,
|
||||
};
|
||||
|
||||
// This functions performs saturated addition of two u8 (unsigned 8-bit integer) slices,
|
||||
// but if any addition result is more than guard then it returns GuardOverflow error instead.
|
||||
pub fn numbers_magic(allocator: std.mem.Allocator, a: []const u8, b: []const u8, guard: u8) ![]u8 {
|
||||
if (a.len != b.len) {
|
||||
return error.InequalLengths;
|
||||
}
|
||||
|
||||
var result = try allocator.alloc(u8, a.len);
|
||||
// errdefer is called only when error is returned, so when there is no error normal result will
|
||||
// be returned to the caller (it should not be deallocated in every case, because it would result
|
||||
// in segmentation fault)
|
||||
errdefer allocator.free(result);
|
||||
|
||||
for (0.., result) |idx, _| {
|
||||
// Saturated addition to avoid integer overflow panic.
|
||||
result[idx] = a[idx] +| b[idx];
|
||||
|
||||
if (result[idx] > guard) {
|
||||
return error.GuardOverflow;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
std.debug.print(
|
||||
"This example does not offer runnable code other than tests. Use zig build test to run them :)\n",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
||||
// This numbers_magic call will not generate any error, so try is used.
|
||||
// The result needs to be freed, because there was no error.
|
||||
test "numers magic no error, no memory leak" {
|
||||
const result = try numbers_magic(
|
||||
std.testing.allocator,
|
||||
&.{ 1, 2, 3, 4, 5, 6 },
|
||||
&.{ 2, 1, 3, 7, 4, 2 },
|
||||
50,
|
||||
);
|
||||
defer std.testing.allocator.free(result);
|
||||
}
|
||||
|
||||
// Numbers magic call is expected to return error (40 + 17 > 50), no deallocation is needed here.
|
||||
// and it does not result in any memory leak, because of errdefer inside numbers_magic,
|
||||
// which cleans up in that case.
|
||||
test "numbers magic error, no memory leak" {
|
||||
const result = numbers_magic(
|
||||
std.testing.allocator,
|
||||
&.{ 10, 20, 30, 40, 45, 43 },
|
||||
&.{ 12, 11, 13, 17, 14, 12 },
|
||||
50,
|
||||
);
|
||||
|
||||
try std.testing.expect(result == error.GuardOverflow);
|
||||
}
|
||||
|
||||
// Just to show that there will be memory leak if function succeeded (no error returned).
|
||||
// Errdefer inside numbers_magic won't clean up in this case, so without using
|
||||
// std.testing.allocator.free(...) this will leak memory.
|
||||
// This test will fail, there should be information about this in output e.g. "1 leaked"
|
||||
test "numbers magic no error, memory leak" {
|
||||
_ = try numbers_magic(
|
||||
std.testing.allocator,
|
||||
&.{ 1, 2, 3, 4, 5, 6 },
|
||||
&.{ 2, 1, 3, 7, 4, 2 },
|
||||
50,
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user