Handling error unions in Threads

Hello,
I’ve been trying to build a program in Zig that uses threads for a non-correlated and critical part of the program. The problem lies in the function I need the threads to run returns an error union and I`m not able to handle it. As an example i reproduced the same error in a simpler program.

const std = @import("std");
pub fn main() !void {
    var gpa = std.heap.DebugAllocator(.{}){};
    var pool: std.Thread.Pool = undefined;
    try pool.init(.{ .allocator = gpa.allocator(), .n_jobs = 3 });
    for (0..20) |i| {
        try pool.spawn(work, .{ gpa.allocator(), i });
    }
    defer pool.deinit();
}

fn work(allocator: std.mem.Allocator, num: usize) !void {
    const string = try std.fmt.allocPrint(allocator, "received = {d}\n", .{num});
    std.debug.print("{s}", .{string});
    defer allocator.free(string);
}

the compiler says

/home/gonik/.local/share/mise/installs/zig/0.14.0/lib/std/Thread/Pool.zig:233:13: error: error union is ignored
            @call(.auto, func, closure.arguments);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/gonik/.local/share/mise/installs/zig/0.14.0/lib/std/Thread/Pool.zig:233:13: note: consider using 'try', 'catch', or 'if'

Thank you very much in advance,

The function passed to spawn cannot return an error. See also `Thread.Pool.spawn` doesn't allow functions with same signatures as `Thread.spawn` does · Issue #18810 · ziglang/zig · GitHub

If you replace work’s return type with void and catch the error from allocPrint, it’ll compile.

5 Likes