Print an error in 0.15.1?

Here is some code:

const std = @import("std");

pub fn main() void {
    std.debug.print("Error: {!}", .{ error.TestError });
}

In 0.14 this prints:

Error: error.TestError

But in 0.15 I get a compiler error:

An error occurred:
/usr/local/bin/lib/std/Io/Writer.zig:1771:5: error: invalid format string '!' for type 'error{TestError}'
    @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    printValue__anon_22746: /usr/local/bin/lib/std/Io/Writer.zig:1246:58
    print__anon_22688: /usr/local/bin/lib/std/Io/Writer.zig:700:25
    7 reference(s) hidden; use '-freference-trace=9' to see all references

Why? According to Zig Documentation {!} is still the correct way to format errors, right?

2 Likes

I think you have to use t now, not sure why ! doesn’t work anymore, maybe so that you explicitly distinguish between error-sets and error-unions.

Notice that this works:

const std = @import("std");

pub fn foo() !i32 {
    return error.FooError;
}
pub fn bar() !i32 {
    return 4;
}

pub fn main() void {
    std.debug.print("Error: {t}\n", .{error.TestError});
    std.debug.print("Error: {!}\n", .{foo()});
    std.debug.print("Error: {!}\n", .{bar()});
}
2 Likes

You can print error values without t, and it has slightly different behaviour depending on which variant you use:

const std = @import("std");

pub fn main() void {
    std.debug.print("{{t}}: {t}\n", .{error.TestError});
    std.debug.print("{{}}: {}\n", .{error.TestError});
}

Prints:

{t}: TestError
{}: error.TestError
2 Likes