Zig by Example
Zig by Example

Errors

< 1 min read

Errors

In Zig, errors are values rather than exceptions. An error union type is written ErrorSet!T.

const std = @import("std");

// Define an error set
const ParseError = error{
    InvalidCharacter,
    Overflow,
    Empty,
};

fn parsePositive(s: []const u8) ParseError!u32 {
    if (s.len == 0) return ParseError.Empty;
    var result: u32 = 0;
    for (s) |c| {
        if (c < '0' or c > '9') return ParseError.InvalidCharacter;
        result = result * 10 + (c - '0');
    }
    return result;
}

pub fn main() void {
    // catch — handle or transform the error
    const n = parsePositive("123") catch |err| {
        std.debug.print("error: {}\n", .{err});
        return;
    };
    std.debug.print("parsed: {d}\n", .{n});

    // catch with a default value
    const m = parsePositive("abc") catch 0;
    std.debug.print("default: {d}\n", .{m});

    // if/else unwrap, then switch on the error set
    if (parsePositive("")) |v| {
        std.debug.print("ok: {d}\n", .{v});
    } else |err| switch (err) {
        error.Empty => std.debug.print("empty input\n", .{}),
        error.InvalidCharacter => std.debug.print("bad char\n", .{}),
        error.Overflow => std.debug.print("overflow\n", .{}),
    }
}

Inside a function that itself returns an error union, you can try foo() — that bubbles the error up right away. Reach for catch when you want to handle it.

Zig by Example
Zig by Example

by Dariush Abbasi

A hands-on introduction to Zig via annotated examples. Covers the language from Hello World through memory allocation, concurrency, networking, and C interop.

View book →