4 ms·
The problem is that in other languages, it's common to do this sort of idiom throw new Error("Expected foo, found bar at line " + line) // ...then els
by lhorie 5y ago
The problem is that in other languages, it's common to do this sort of idiom
throw new Error("Expected foo, found bar at line " + line)
// ...then elsewhere
catch (e) {
log("In file " + file + ":\n" + e.message);
}
In zig, you can't attach arbitrary strings to errors because errors are effectively enums (in the sense of that constant names map exclusively to ints). You can only do this `try callMe() catch return error.Something` (The `return error.Something` part is zig's "equivalent" to `throw error`, but notice how I can't tack on the error message string to the error)
`try` only shortcircuits into the `catch return` expression for errors, but for cases like parsers you want to shortcircuit and bubble up error messages simultaneously. You can kinda do weird workarounds by having a pointer to an error field in your input struct and mutating that prior to returning an error value, and/or doing weird nullable-to-sentinel-value-promotion shenanigans with idioms like `callMeMaybe() orelse return someSentinel("Expected foo")` to simulate the early-return-from-expression semantics from `try callMe() catch return error.Something`.
- Hoppetosse 5y agoIf you want to handle the error and also bubble it up, maybe even changing the what error bubbles up, you can just return an error from within the catch block after doing whatever handling you want. Either the captured error or something else. Specifically for recursive descent parsers, I pass around a reference to an regular struct that acts as an ErrorInfo object, and use that to pass diagnostic information up the stack. Control flow is still managed by the error returns, any additional info goes in the parameter. There is (was?) a proposal to add that capability to the language but Im not sure it had much traction.
- lhorie 5y agoYeah I think a lot of people have been settling for that pattern, but it's admittedly not ideal, in the same way that it's generally preferable to work with discrete values in a functional/pure fashion than shuffling values in and out of an out param list everywhere.