feat(Lua): add some error handling

This commit is contained in:
Titanium Brain 2026-06-04 19:34:57 +01:00
commit a70d301b6b

View file

@ -123,9 +123,10 @@ pub fn LuaParser(comptime Struct: type) type {
pub fn init(
allocator: std.mem.Allocator,
// io: std.Io,
path: []const u8,
) !Self {
var maybe_load_error: ?anyerror = null;
errdefer |err| maybe_load_error = err;
var lua: *Lua = try .init(allocator);
defer lua.deinit();
@ -135,22 +136,22 @@ pub fn LuaParser(comptime Struct: type) type {
const spath: [:0]const u8 = try allocator.dupeSentinel(u8, path, 0);
defer allocator.free(spath);
lua.doFile(spath) catch {
const error_str = lua.toString(-1) catch unreachable;
const lua_str = try allocator.dupeSentinel(u8, error_str, 0);
_ = lua_str; // TODO add error logging
return error.LuaError;
};
var data: Struct = .{};
switch (@typeInfo(Struct)) {
.@"struct" => |struc| {
inline for (struc.fields) |field| {
try setField(allocator, lua, field, &data);
setField(allocator, lua, field, &data) catch {};
}
},
else => @compileError("Expected a struct."),
}
return .{ .structure = data, .errors = .empty, .maybe_load_error = null };
if (global_errors.items.len != 0) {
maybe_load_error = error.InvalidConfig;
}
return .{ .structure = data, .errors = global_errors, .maybe_load_error = maybe_load_error };
}
pub fn setField(allocator: std.mem.Allocator, lua: *Lua, comptime field: std.builtin.Type.StructField, data: *Struct) !void {
_ = lua.getGlobal("ly");
@ -177,6 +178,9 @@ pub fn LuaParser(comptime Struct: type) type {
return;
}
const actual_type_info = @typeInfo(actual_type);
errdefer |err| errorHandler(@typeName(field.type), field.name, lua.toStringEx(-1), err);
// dispatch depending on type
if (actual_type_info == .int and is_optional) {
if (lua.isInteger(-1)) {
@ -217,6 +221,7 @@ pub fn LuaParser(comptime Struct: type) type {
const value = try lua.toNumber(-1);
@field(data, field.name) = @floatCast(value);
} else if (actual_type_info == .bool) {
if (!lua.isBoolean(-1)) return error.ExpectedBoolean;
const value = lua.toBoolean(-1);
@field(data, field.name) = value;
} else if (actual_type == []const u8 or actual_type == [:0]const u8) {
@ -232,7 +237,7 @@ pub fn LuaParser(comptime Struct: type) type {
const value = try lua.toString(-1);
const variant = std.meta.stringToEnum(actual_type, value) orelse return error.InvalidVariant;
@field(data, field.name) = variant;
}
} else unreachable;
}
pub fn deinit(self: *Self) void {
@ -246,5 +251,14 @@ pub fn LuaParser(comptime Struct: type) type {
global_errors.deinit(temporary_allocator);
}
fn errorHandler(type_name: []const u8, key: []const u8, value: []const u8, err: anyerror) void {
global_errors.append(temporary_allocator, .{
.type_name = temporary_allocator.dupe(u8, type_name) catch return,
.key = temporary_allocator.dupe(u8, key) catch return,
.value = temporary_allocator.dupe(u8, value) catch return,
.error_name = @errorName(err),
}) catch return;
}
};
}