Zig DISCUSSION

Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

Started by anis Zig error uniontry and catchparseInterrdefererror handling
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

anis Zig Forum
#1

My program reads a line such as baud=115200 from a configuration file and converts the number with std.fmt.parseInt(u32, text, 10). The result cannot be used directly: the compiler says the value is an error union, not a u32. I have seen try, catch, catch unreachable and if (...) |v| {} else |err| {} in examples and I am not sure which one is appropriate where.

What is the difference between them, and how do I fall back to a default of 9600 when the text is not a valid number?

Community replies 4

Re: Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

#2

parseInt returns an error union: either a u32 or one of two errors, error.InvalidCharacter or error.Overflow. You must unwrap it before use, and the compiler will not let you silently drop the error case.

try expr is shorthand for expr catch |err| return err: on success you get the value, on failure the current function returns the error to its caller. It is only allowed in a function whose return type can carry an error, for example fn load() !Config.

Re: Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

#3

For a default, use catch with a value: const baud = std.fmt.parseInt(u32, text, 10) catch 9600;. The right-hand side must have the same type as the success value.

If you want to act on the specific error, capture it: catch |err| switch (err) { error.Overflow => 4_000_000, error.InvalidCharacter => 9600 }. The switch has to cover every error in the set, so a case you forgot is reported at compile time.

Re: Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

#4

The if form is for when both branches need several statements: if (std.fmt.parseInt(u32, text, 10)) |value| { ... } else |err| { ... }.

catch unreachable is a promise that the error cannot happen. In Debug and ReleaseSafe builds a broken promise panics; in ReleaseFast it is undefined behaviour. It is reasonable for a constant you wrote yourself, such as parseInt(u8, "42", 10), and wrong for anything read from a file or a serial port.

Re: Zig error unions: when should I use try, catch or if-else to handle a parseInt failure?

#5

Two practical causes of InvalidCharacter with input that looks fine: the key was not split off, or the text still has its line ending or spaces attached. "115200\r" is not a number. Trim first with std.mem.trim(u8, text, " \r\n\t").

Also check the range: parseInt(u8, "300", 10) returns error.Overflow because 300 does not fit in 8 bits, so choose the integer type from the values you expect. And when a function acquires something before a step that can fail, pair it with errdefer, which runs its cleanup only if the function exits with an error.

TEP COMMUNITY