feat: use explicit error handling for all startup errors
This commit is contained in:
		
							parent
							
								
									fc3224137d
								
							
						
					
					
						commit
						a1b2737c5d
					
				
					 12 changed files with 116 additions and 50 deletions
				
			
		| 
						 | 
				
			
			@ -31,7 +31,7 @@ on_render: *const fn (ctx: ?*anyopaque, theme: *const Widget.Theme) void = on_re
 | 
			
		|||
after_render: *const fn (ctx: ?*anyopaque, theme: *const Widget.Theme) void = on_render_default,
 | 
			
		||||
on_resize: *const fn (ctx: ?*anyopaque, self: *Self, pos_: Widget.Box) void = on_resize_default,
 | 
			
		||||
 | 
			
		||||
pub fn createH(allocator: Allocator, parent: Plane, name: [:0]const u8, layout_: Layout) !*Self {
 | 
			
		||||
pub fn createH(allocator: Allocator, parent: Plane, name: [:0]const u8, layout_: Layout) error{OutOfMemory}!*Self {
 | 
			
		||||
    const self: *Self = try allocator.create(Self);
 | 
			
		||||
    self.* = try init(allocator, parent, name, .horizontal, layout_, Box{});
 | 
			
		||||
    self.plane.hide();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,9 @@ const FileListType = enum {
 | 
			
		|||
    find_in_files,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn create(allocator: std.mem.Allocator) !Widget {
 | 
			
		||||
pub const CreateError = error{ OutOfMemory, ThespianSpawnFailed };
 | 
			
		||||
 | 
			
		||||
pub fn create(allocator: std.mem.Allocator) CreateError!Widget {
 | 
			
		||||
    const self = try allocator.create(Self);
 | 
			
		||||
    self.* = .{
 | 
			
		||||
        .allocator = allocator,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,13 +8,17 @@ const Plane = @import("renderer").Plane;
 | 
			
		|||
 | 
			
		||||
pub const Style = enum { none, grip };
 | 
			
		||||
 | 
			
		||||
pub fn create(allocator: std.mem.Allocator, parent: Plane, config: []const u8, style: Style, event_handler: ?EventHandler) !Widget {
 | 
			
		||||
pub fn create(allocator: std.mem.Allocator, parent: Plane, config: []const u8, style: Style, event_handler: ?EventHandler) error{OutOfMemory}!Widget {
 | 
			
		||||
    var w = try WidgetList.createH(allocator, parent, "statusbar", .{ .static = 1 });
 | 
			
		||||
    if (style == .grip) w.after_render = render_grip;
 | 
			
		||||
    w.ctx = w;
 | 
			
		||||
    var it = std.mem.splitScalar(u8, config, ' ');
 | 
			
		||||
    while (it.next()) |widget_name|
 | 
			
		||||
        try w.add(try status_widget.create(widget_name, allocator, w.plane, event_handler) orelse continue);
 | 
			
		||||
    while (it.next()) |widget_name| {
 | 
			
		||||
        try w.add(status_widget.create(widget_name, allocator, w.plane, event_handler) catch |e| switch (e) {
 | 
			
		||||
            error.OutOfMemory => return error.OutOfMemory,
 | 
			
		||||
            error.WidgetInitFailed => null,
 | 
			
		||||
        } orelse continue);
 | 
			
		||||
    }
 | 
			
		||||
    return w.widget();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,14 +19,20 @@ tz: zeit.timezone.TimeZone,
 | 
			
		|||
const Self = @This();
 | 
			
		||||
 | 
			
		||||
pub fn create(allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) @import("widget.zig").CreateError!Widget {
 | 
			
		||||
    var env = std.process.getEnvMap(allocator) catch |e| return tp.exit_error(e, @errorReturnTrace());
 | 
			
		||||
    var env = std.process.getEnvMap(allocator) catch |e| {
 | 
			
		||||
        std.log.err("clock: std.process.getEnvMap failed with {any}", .{e});
 | 
			
		||||
        return error.WidgetInitFailed;
 | 
			
		||||
    };
 | 
			
		||||
    defer env.deinit();
 | 
			
		||||
    const self: *Self = try allocator.create(Self);
 | 
			
		||||
    self.* = .{
 | 
			
		||||
        .allocator = allocator,
 | 
			
		||||
        .plane = try Plane.init(&(Widget.Box{}).opts(@typeName(Self)), parent),
 | 
			
		||||
        .on_event = event_handler,
 | 
			
		||||
        .tz = zeit.local(allocator, &env) catch |e| return tp.exit_error(e, @errorReturnTrace()),
 | 
			
		||||
        .tz = zeit.local(allocator, &env) catch |e| {
 | 
			
		||||
            std.log.err("clock: zeit.local failed with {any}", .{e});
 | 
			
		||||
            return error.WidgetInitFailed;
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
    try tui.message_filters().add(MessageFilter.bind(self, receive_tick));
 | 
			
		||||
    self.update_tick_timer(.init);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ pub fn create(allocator: std.mem.Allocator, parent: Plane, event_handler: ?Event
 | 
			
		|||
    };
 | 
			
		||||
    logview.init(allocator);
 | 
			
		||||
    try tui.message_filters().add(MessageFilter.bind(self, receive_log));
 | 
			
		||||
    try log.subscribe();
 | 
			
		||||
    log.subscribe() catch return error.WidgetInitFailed;
 | 
			
		||||
    return Widget.to(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ const widgets = std.static_string_map.StaticStringMap(CreateFunction).initCompti
 | 
			
		|||
    .{ "keybind", @import("keybindstate.zig").create },
 | 
			
		||||
    .{ "tabs", @import("tabs.zig").create },
 | 
			
		||||
});
 | 
			
		||||
pub const CreateError = error{ OutOfMemory, Exit };
 | 
			
		||||
pub const CreateError = error{ OutOfMemory, WidgetInitFailed };
 | 
			
		||||
pub const CreateFunction = *const fn (allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!Widget;
 | 
			
		||||
 | 
			
		||||
pub fn create(name: []const u8, allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler) CreateError!?Widget {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,11 +84,24 @@ fn start(args: StartArgs) tp.result {
 | 
			
		|||
    tp.receive(&self.receiver);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn init(allocator: Allocator) !*Self {
 | 
			
		||||
const InitError = error{
 | 
			
		||||
    OutOfMemory,
 | 
			
		||||
    UnknownTheme,
 | 
			
		||||
    ThespianMetronomeInitFailed,
 | 
			
		||||
    ThespianMetronomeStartFailed,
 | 
			
		||||
    ThespianTimeoutInitFailed,
 | 
			
		||||
    ThespianSignalInitFailed,
 | 
			
		||||
    ThespianSpawnFailed,
 | 
			
		||||
} || renderer.Error ||
 | 
			
		||||
    root.ConfigDirError ||
 | 
			
		||||
    root.ConfigWriteError ||
 | 
			
		||||
    keybind.LoadError;
 | 
			
		||||
 | 
			
		||||
fn init(allocator: Allocator) InitError!*Self {
 | 
			
		||||
    var conf, const conf_bufs = root.read_config(@import("config"), allocator);
 | 
			
		||||
    defer root.free_config(allocator, conf_bufs);
 | 
			
		||||
 | 
			
		||||
    const theme_ = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return tp.exit("unknown theme");
 | 
			
		||||
    const theme_ = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return error.UnknownTheme;
 | 
			
		||||
    conf.theme = theme_.name;
 | 
			
		||||
    conf.whitespace_mode = try allocator.dupe(u8, conf.whitespace_mode);
 | 
			
		||||
    conf.input_mode = try allocator.dupe(u8, conf.input_mode);
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +174,7 @@ fn init(allocator: Allocator) !*Self {
 | 
			
		|||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn init_input_namespace(self: *Self) !void {
 | 
			
		||||
fn init_input_namespace(self: *Self) InitError!void {
 | 
			
		||||
    var mode_parts = std.mem.splitScalar(u8, self.config_.input_mode, '/');
 | 
			
		||||
    const namespace_name = mode_parts.first();
 | 
			
		||||
    keybind.set_namespace(namespace_name) catch {
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +185,7 @@ fn init_input_namespace(self: *Self) !void {
 | 
			
		|||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn init_delayed(self: *Self) !void {
 | 
			
		||||
fn init_delayed(self: *Self) command.Result {
 | 
			
		||||
    self.delayed_init_done = true;
 | 
			
		||||
    if (self.input_mode_) |_| {} else {
 | 
			
		||||
        if (self.delayed_init_input_mode) |delayed_init_input_mode| {
 | 
			
		||||
| 
						 | 
				
			
			@ -218,9 +231,9 @@ fn deinit(self: *Self) void {
 | 
			
		|||
    self.allocator.destroy(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn listen_sigwinch(self: *Self) tp.result {
 | 
			
		||||
fn listen_sigwinch(self: *Self) error{ThespianSignalInitFailed}!void {
 | 
			
		||||
    if (self.sigwinch_signal) |old| old.deinit();
 | 
			
		||||
    self.sigwinch_signal = tp.signal.init(std.posix.SIG.WINCH, tp.message.fmt(.{"sigwinch"})) catch |e| return tp.exit_error(e, @errorReturnTrace());
 | 
			
		||||
    self.sigwinch_signal = try tp.signal.init(std.posix.SIG.WINCH, tp.message.fmt(.{"sigwinch"}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn update_mouse_idle_timer(self: *Self) void {
 | 
			
		||||
| 
						 | 
				
			
			@ -465,7 +478,7 @@ fn active_event_handler(self: *Self) ?EventHandler {
 | 
			
		|||
    return mode.event_handler orelse mode.input_handler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn dispatch_flush_input_event(self: *Self) !void {
 | 
			
		||||
fn dispatch_flush_input_event(self: *Self) error{ Exit, NoSpaceLeft }!void {
 | 
			
		||||
    var buf: [32]u8 = undefined;
 | 
			
		||||
    const mode = self.input_mode_ orelse return;
 | 
			
		||||
    try mode.input_handler.send(tp.self_pid(), try tp.message.fmtbuf(&buf, .{"F"}));
 | 
			
		||||
| 
						 | 
				
			
			@ -627,7 +640,7 @@ pub fn refresh_hover() void {
 | 
			
		|||
    _ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn save_config() !void {
 | 
			
		||||
pub fn save_config() (root.ConfigDirError || root.ConfigWriteError)!void {
 | 
			
		||||
    const self = current();
 | 
			
		||||
    try root.write_config(self.config_, self.allocator);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue