Error Handling

Did you see the !voidreturn type of the mainfunction from earlier? That is Zig's way of indicating that the mainfunction could possibly return an error. Error handling is a feature that was designed carefully in Zig, and worth exploring before we go further.

Defining an error

An error is defined in a similar way to an enum. You can also use ||to combine different error types together. Here are some errors from the standard library.

// in std/mem/Allocator.zig
pub const Error = error{
    OutOfMemory,
};

// in std/io.zig
pub const NoEofError = ReadError || error{
    EndOfStream,
};

// in std/dynamic_library.zig
const ElfDynLibError = error{
    FileTooBig,
    NotElfFile,
    NotDynamicLibrary,
    MissingDynamicLinkingInformation,
    ElfStringSectionNotFound,
    ElfSymSectionNotFound,
    ElfHashTableNotFound,
} || posix.OpenError || posix.MMapError;

Returning errors

After defining your error, you have to indicate that a function you've written can possibly return an error. This is done by placing the error name, then a !, then the actual return type.

In the following example, the function myFunctioncan only return MyError. There is no other possible error type. On the other hand, myOtherFunctioncould possibly return other error types — its error type is inferred from the function body.

Zig also has an anyerrortype, which represents the union of all the error types across the entire program. So pretty much any error in the program.

Handling errors

You can either use tryto propagate errors from functions that you call, or catchto handle the errors at the call site. In Zig, errors must be handled (eventually), otherwise you'll get a compiler error.

Last updated