# Zig Error Handling Quick Summary
To start, what we call `Result<T,E>` Zig calls `E!T`. Zig doesn't actually have generics, but this special error handling type is built into the compiler so you can write it with whatever combination of success type and and error type in a way that's *close enough* to generics in this case.
An error type in Zig is *separate* from a normal Zig enum, and it's what Rust would call a "C-style Enum", it's a series of named tags that each have no fields. They've got some [examples](https://ziglang.org/documentation/master/#Errors) in their docs:
```zig
// stuff like this
const FileOpenError = error {
AccessDenied,
OutOfMemory,
FileNotFound,
};
```
So with this defined, your function can return something like `FileOpenError!u64` which, again, would be written as `Result<u64, FileOpenError>` in Rust.
**But here's where it gets good:** All error tags are implicitly also added to an `anyerror` automatic type by the compiler. You can have a function return a specific error type if you want to be able to exhaustively handle errors, OR you can have a function return an `anyerror` by omitting an error type on the left of the `!` symbol (eg: `!u64`), in which case the function can return any error tag it wants, including that it can make up an error tag right there within the function definition. Callers can handle specific errors and will usually also need to have an else case on their switch statement (think the `_ =>` match arm in Rust, like with a `#[non_exhaustive]` enum). The final contents of the `anyerror` enum is automatically collected from the union of all error tags of all functions used anywhere in the entire program.
Of course this shouldn't be the only way to handle errors in Rust, but having some sort of AnyError implicit global enum would be super cool and super "no alloc" friendly.