I recently followed the write a terminal editor tutorial from here: https://viewsourcecode.org/snaptoken/kilo/ in zig 0.16.0 and since there is a lot of writing, which can fail, to stdout() there are A LOT of try keywords in my code (Flashback to .unwrap() and .expect("..") in my rust code). And it got me thinking why exactly do we need try?
We need to deal with the errors anyway why not just automatically raise the error if one occurs (which in reality is what you do in most cases) and have just code like catch for when we deal with it now? This would cleanup the code a lot in my opinion.
fn test_method() !void {
let v1 = method1(); // If error automatically propagates.
method2() catch |err| {
// DEAL WITH ERROR here no auto propagation.
}
method3() catch-to result; // Treat result later (Adds bew keyword).
// result above would be the same error union type as the method return type.
// Alternatively
const result !: method3() // !: is like = but cathes the error union.
}
Of course there can be a much better keyword then !: It’s just a placeholder for discussion.
Have a dedicated keyword for when you DON’T want to propagate the error instead of a dedicated keyword for when you DO would really cleanup a lot of code from my point of view.
I think this still hold for the zig zen of communicating intent clearly as you see right there where the error is treated if not you know it bubbles up the chain.
I would like to hear some opinions on this topic from you all.
try is a visual marker for function calls that can fail, and conversely the absence of indicates that a given function call cannot fail. if you make it implicit, then when reading code you will not immediately know if a given function call will cause control flow to change or not, and that would suck.
If you find try annoying then it probably means that you are not handling your errors properly. If you find yourself bubbling all the errors up to main(), then you are no better off than using catch @panic everywhere, which is not a good error handling strategy.
e.g. if reading a file fails and you bubble up the error then the user will just see a completely useless error.FileNotFound or error.AccessDenied as the program crashes.
However if you handle the error locally by e.g. logging the file path together with the error and panicing (or ideally continuing if possible, in a GUI application you could also display an error message box), then the user can go into their file system and fix the file permissions or whatever.