The article pretty much says this as well, but a concise way I saw Andrew Kelley put it recently in the context of Zig (but it seems to apply well for any language that has errors-as-values + panics) is: "Assertions for programmer mistakes; errors for user mistakes."[0] One interesting difference between Zig and other languages with similar error stories (Rust, Go) is that panicking can be handled but not recovered .…
From my experience, Zig is the worst at error handling. Not that the language itself make it hard, on the contrary, but the standard library itself is littered with opinionated error handling that straight up panic with no recovery at every corner. For instance, it was decided that the kernel returning EINVAL for any syscall is worth panicking, even though there are a lot of cases where that is recoverable. The answe…
> It should be handled on a case-by-case basis. For some syscalls, EINVAL should be unreachable because it can only mean something like an invalid pointer address being passed to the kernel, or invalid flags.
> However, as you pointed out, some kernel APIs unfortunately have decided to dual-purpose this error code to mean other things, in which case we must to handle the ambiguity by mapping it to an error code. We had to make this change with EBADF recently for some syscalls, for example.
> I do want to keep the error sets clean, however, so I am opposed to a blanket modification of all EINVAL code sites without cause.
Source: https://github.com/ziglang/zig/issues/6925#issuecomment-7214...