How do deal with Zig error not being to contain data?

Quite a few people in the Zig community have rallied around the “Diagnostics pattern” where you return and handle errors per usual, but also allow the caller to interrogate a Diagnostics instance when an error happens. This contains useful information about the error, such as col/line for a parser error, or maybe an errorstring/code combination for a file error.

Depending on situation, the Diagnostics instance can be passed in to every relevant fallible function, or be part of initialization for session-oriented situations.

Here are some examples:

Clap, where you pass diagnostics as an argument: zig-clap/example/simple.zig at a4e784da8399c51d5eeb5783e6a485b960d5c1f9 · Hejsil/zig-clap · GitHub

The Scanner in std lib, where you can ask for diagnostics (if enabled) when errors occur: zig/lib/std/json/scanner.zig at 8f8f37fb0fe0ab8d98ca54ba6b51ce3d84222082 · ziglang/zig · GitHub

For my own, I used the approach in Stitch, where you can also ask for diagnostics when an error occurs in the session you have with the library: stitch/src/lib.zig at 9b82da85c70f5c702db9e4e8d498a9661c40ae5b · cryptocode/stitch · GitHub

The last one is kinda interesting in that it uses InKryption’s idea of using pub const Diagnostic = union(std.meta.FieldEnum(MyErrorType)) to make sure error enums and diagnostics are always kept in sync. If you forget to sync up, you get a compile error. Very nice imo!

8 Likes