Is there any way to address this?

Currently I’m doing a little project to learn Zig and network protocols, TCP, UDP, IRC, Tor, etc., and, doing a practical implementation: a file-transfer application, but i had an issue when it iterates over the arguments of the program to read the files to send:

    // --cut--
                        var buff = gpa.create([1.5*GB]u8) catch @panic("unhandled memory allocation error in main.evalArgs().");
                        defer gpa.destroy(buff);
                        print("    \x1b[3;1m{s}\x1b[0;1m: ", .{data});
                        var file: []u8 = undefined;
                        file = std.Io.Dir.cwd().readFile(io, data, buff[0..]) catch |err| {
                            switch (err) {
                                std.Io.Dir.PathNameError.BadPathName => {
                                    parse.badFilef("bad path name");
                                    exit(1);
                                },
                                std.Io.File.OpenError.FileNotFound => {
                                    parse.badFilef("not found");
                                    exit(1);
                                },
                                std.Io.File.OpenError.IsDir => {
                                    var dir = std.Io.Dir.cwd().openDir(io, data, .{ .iterate=true, .access_sub_paths=true}) catch @panic("");
                                    var directory = dir.iterate();
                                    if (directory.next(io) catch |errDir| { log("error: {t}", .{errDir}); exit(1);}) |subData| {
                                         file = dir.readFile(io, subData.name, buff[0..]) catch @panic("");
                                    }else{ unreachable; }
                                    print("\x1b[0;1m", .{});
                                    // print("is a directory", .{});
                                },
                                std.Io.File.OpenError.NotDir => {
                                    parse.badFilef("isn't a directory");
                                    exit(1);
                                },
                                std.Io.File.OpenError.PermissionDenied => {
                                    parse.badFilef("permission denied");
                                    exit(1);
                                },
                                std.Io.File.OpenError.ReadOnlyFileSystem => {
                                    parse.badFilef("is a read-only");
                                    exit(1);
                                },
                                std.Io.File.OpenError.AccessDenied => {
                                    parse.badFilef("access denied");
                                    exit(1);
                                },
                                else => @panic(""),
                            }
                        };
    // --cut--

And the compiler reject this:

Because the catch don’t return nothing (void) but the file variable is type [ ]u8.

~/project>> zig build
install
└─ install creep
   └─ compile exe creep Debug native 1 errors
src/main.zig:73:91: error: expected type '[]u8', found 'void'
                        file = std.Io.Dir.cwd().readFile(io, data, buff[0..]) catch |err| {
                                                                                          ^
referenced by:
    main: src/main.zig:41:13
    callMain [inlined]: /home/user/Projects/Zig/zig-0.16.0/lib/std/start.zig:737:30
    callMainWithArgs [inlined]: /home/user/Projects/Zig/zig-0.16.0/lib/std/start.zig:638:20
    posixCallMainAndExit: /home/user/Projects/Zig/zig-0.16.0/lib/std/start.zig:590:38
    2 reference(s) hidden; use '-freference-trace=6' to see all references
error: 1 compilation errors
failed command: /home/user/Projects/Zig/zig-0.16.0/zig build-exe -ODebug --dep creep -Mroot=/home/user/Projects/Zig/creep/creep-cli/src/main.zig -Mcreep=/home/user/Projects/Zig/creep/creep-cli/src/root.zig --cache-dir .zig-cache --global-cache-dir /home/user/.cache/zig --name creep --zig-lib-dir /home/user/Projects/Zig/zig-0.16.0/lib/ --listen=-

Build Summary: 0/3 steps succeeded (1 failed)
install transitive failure
└─ install creep transitive failure
   └─ compile exe creep Debug native 1 errors

error: the following build command failed with exit code 1:
.zig-cache/o/15fbd03d421235aaee722fa9dc85488e/build /home/user/Projects/Zig/zig-0.16.0/zig /home/user/Projects/Zig/zig-0.16.0/lib /home/user/Projects/Zig/creep/creep-cli .zig-cache /home/user/.cache/zig --seed 0x99fa6f41 -Z8f07c54f25657609

And then:

Couldn’t be a way of kinda, returning from the catch?
Imagine something like this:

fn otherFunc() someType {...}
fn someFunc() someType {...}

// --cut--
    const variable = someFunc() catch |err| {
        switch (err) {
            error.some => {
                  .. = otherFunc();
            },
        }
    };
// --cut--

Did you paste the wrong code/compiler output? The void![]u8 line is nowhere in the code you posted. void!T is not a valid type (if you need an empty error set, use error{}![]u8).

Please either post the full code or a minimal runnable example that others can run, otherwise people won’t be able to provide useful guidance.

1 Like

Yeah, sorry I tried something stupid, editing it now!.

I see. The functionality you’re asking for is returning values from labeled blocks with break :label value.

const value = someFunc() catch |err| blk: { // note the label
    switch (err) {
        error.Foo => {
            const fallback_value = otherFunc();
            // break from the labeled block with a value
            break :blk fallback_value;
        },
        else => @panic("TODO"),
    };
};
2 Likes

Thank you very much, It compiled.