# Error Handling

Did you see the `!void`return type of the `main`function from earlier? That is Zig's way of indicating that the `main`function 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.

```zig
// 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 `myFunction`can *only* return `MyError`. There is no other possible error type. On the other hand, `myOtherFunction`could possibly return other error types — its error type is *inferred* from the function body.

```zig
const MyError = error{
    FooReason,
    BarReason,
    AnotherReason,
};

pub fn myFunction(x: i32) MyError!i32 {
    if (x < 43) {
        // Simply return the error if you encounter an error condition, instead
        // of returning the result.
        return MyError.FooReason;
    } else if (x > 43) {
        return MyError.BarReason;
    } else {
        return 33;
    }
}

// Here the error type is inferred, instead of being explicitly defined.
pub fn myOtherFunction(x: i32) !i32 {
    if (x < 99) {
        return MyError.AnotherReason;
    } else if (x > 99) {
        return MyError.BarReason;
    } else {
        return 22;
    }
}
```

{% hint style="info" %}
Zig also has an `anyerror`type, which represents the union of all the error types across the entire program. So pretty much *any error in the program*.
{% endhint %}

## Handling errors

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

```zig
pub fn main() !void {
    // This will propagate the error up to the caller of this function.
    // In the case of the `main` function, it would end the program.
    const my_function_result = try myFunction(43);
    std.debug.print("The result of myFunction is: {}\n", .{my_function_result});

    // Instead of propagating the error, you can also handle it.
    const my_other_function_result = myOtherFunction(43) catch |err| {
        switch (err) {
            MyError.FooReason => std.debug.print("FooReason\n", .{}),
            MyError.BarReason => std.debug.print("BarReason\n", .{}),
            MyError.AnotherReason => std.debug.print("AnotherReason\n", .{}),
        }
        // Return early from the main function.
        return;
    };
    std.debug.print("The result of myOtherFunction is: {}\n", .{my_other_function_result});
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wiki.nushackers.org/hackerschool/introduction-to-zig/error-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
