I’m trying to create a userland error type that’s somwhat similar to JavaScript’s errors: the error may hold its own data as well as have a cause
(a child error). The memory footprint isn’t a concern, although in an attempt to simplify memory ownershp, the outmost error is assumed to own the memory and deinit
ing it is expected to deinit all child errors.
I’m new to Zig, and with what I know so far, I tried putting together the following error type:
fn Error(Data: type, Child: type) type {
return struct {
const Self = @This();
name: []const u8,
data: *Data,
cause: ?*Child,
_is_error: bool = true,
gpa_pointer: *GeneralPurposeAllocator(.{}),
allocator: std.mem.Allocator,
pub fn init(
parent_allocator: Allocator,
name: []const u8,
data: Data,
child: ?Child,
) !Self {
const gpa_pointer = try parent_allocator.create(
GeneralPurposeAllocator(.{}),
);
gpa_pointer.* = .init;
const allocator = gpa_pointer.allocator();
const data_ptr = try allocator.create(Data);
data_ptr.* = data;
return Self{
.name = name,
.data = data_ptr,
.cause = if (child) |c| blk: {
const child_ptr = try allocator.create(Child);
child_ptr.* = c;
break :blk child_ptr;
} else null,
.gpa_pointer = gpa_pointer,
.allocator = allocator,
};
}
pub fn deinit(self: *Self, parent_allocator: Allocator) void {
const is_error = blk: {
var is_error = false;
switch (@typeInfo(self.data)) {
std.builtin.Type.@"struct" => |s| {
inline for (s.fields) |field| {
if (std.mem.eql(
u8,
field.name,
"_is_error",
)) {
is_error = true;
}
}
},
else => {
std.debug.print("no struct\n", .{});
},
}
break :blk is_error;
};
if (is_error) {
self.data.deinit(parent_allocator);
}
self.allocator.destroy(self.data);
parent_allocator.destroy(self.gpa_pointer);
}
};
}
The code doesn’t compile. Within the deinit
function, the argument to switch
produces an error:
error: unable to resolve comptime value
switch (@typeInfo(self.data)) {
~~~~^~~~~
note: types must be comptime-known
How to fix this error?
Overall, is there a better way of achieving having errors with custom data that keep track of what caused them?