4 ms·
Why Use Structured Errors in Rust Applications?
- suddenlybananas 1y agoI just wish it were simpler to set up backtraces with thiserror.
- ozgrakkurt 1y agoYou only ever need backtrace with line numbers and error kind enum for library code and app code that is no supposed to fail. For app code that is supposed to fail, you need full custom error setup. For example in a a http server you want to cleanly convert error to http response and a record on server side for viewing later. imo zig implements errors in language pefectly
- nixpulvis 1y agoCan you elaborate on what Zig does that makes it better in your opinion?
- alpaca128 1y agoI don't get what makes Zig errors better. As I understand it they're just named error codes with special syntax for handling them, meaning any more complex error type or any kind of contextual information has to be dealt with separately. If you want to return the location of a syntax error in the input you can't provide that information in the error. Zig has a couple opinionated properties I find strange, but the error handling is the one I find the most puzzling. Meanwhile Rust treats all possible error types the same way as long as they're wrapped in Result.
- anonymoushn 1y agoI think that like actually using Rust and encountering situations where one must define a new error enum that exists only to wrap the values returned by two different fallible functions belonging to different libraries all the time was sufficient to convince me that the situation in Zig is preferable. It's also generally good that users are unable to attach strings to their errors when using the built-in error handling, in the sense that things that are usually bad ideas ought to be a bit more difficult, so that users do not end up doing them all the time.
- littlestymaar 1y ago> in the sense that things that are usually bad ideas ought to be a bit more difficult, I didn't know that the Zig folks had embraced the Go philosophy of “the language designer knows better than you” for trivial stuff like that. That's the kind of behavior that lead people to build their own version of things, incompatible with the whole ecosystem, just to be free from the petty arbitrary limitation.
- alpaca128 1y agoThey also settled the tabs vs. spaces debate by declaring tabs a syntax error, end of discussion. Same with unused variables which are a compile-time error. The thing is, I don't disagree with the fundamental arguments that led to these decisions, I just think it goes a step too far and they're trying too hard. I understand they aim to reduce footguns in C with that language but that doesn't mean they have to prevent someone from wearing the wrong shoe for the occasion.
- littlestymaar 1y ago> They also settled the tabs vs. spaces debate by declaring tabs a syntax error, Did Zig really do that? Because even go didn't, it's just the default of gofmt and you can't override it, but not a hard error. > Same with unused variables which are a compile-time error. Which is a pain in the ass for anyone attempting to refactor or iterate on a go codebase. A warning is just the better option for this kind of things. That's the entire purpose of the concept of warning.
- alpaca128 1y agohttps://github.com/ziglang/zig/issues/544#issuecomment-618072318 https://github.com/ziglang/zig/issues/544#issuecomment-61807... > In order to simplify everything, tabs are not allowed. Spaces are necessary; we can't ban spaces. They seem to be open to the alternative but not to a solution that isn't forced on people: > Maybe someday, we'll switch to tabs for indentation, spaces for alignment and make it a compile error if they are incorrectly mixed Zig already has a builtin code formatter that automatically changes formatting to their preference, but that's not enough. > That's the entire purpose of the concept of warning Yes, but as far as I know the Zig compiler cannot emit warnings, only errors. Because warnings are potential footguns too and we can't have that.
- layer8 1y ago“Not supposed to fail” can be context-dependent though, and/or depend on the specific error (code), so whether you need a stack trace or not may only be decidable after the fact.
- arccy 1y agoHaving had to work with various application written in rust... i find they have some of the most terrible of errors. "<some low level operation> failed" with absolutely no context on why the operation was invoked in the first place, or with what arguments. This is arguably worse than crashing with a stack trace (at least i can see a call path) or go's typical chain of human annotated error chains.
- nixpulvis 1y agoI don't think this is really a failing of the language, just a bad practice in assuming that you can bubble up a low level error without adding some more context to why it was trigged in this case. Short of matching the error and returning a new error with more info, I'm not sure what the idiomatic solution is personally. But I also haven't spent as much time as I should with error crates. I agree it's an issue, and I hope the community centers around better practices.
- arccy 1y agoI think it is a language issue, if the language makes a bare return much easier than the alternative, then that's what people will be inclined to do.
- nixpulvis 1y agoWhen I say it's not a language issue, that's because I can imagine a crate or design pattern filling this role, and I cannot as easily imagine a change to the language itself that would make it better. But I also haven't given this as much thought as it deserves.
- lifthrasiir 1y agoI recently saw the `error_mancer` crate [1] that automatically generates error types for each function so that error definitions and functions are adjacent to each other. While it wouldn't be sufficient for all cases, I quite liked its approach. [1] https://crates.io/crates/error_mancer https://crates.io/crates/error_mancer
- dlahoda 1y agonice approach, seems would be awesome for http openapi.
- oldpersonintx2 1y agowent down a similar path `anyhow` is a very cool library but in the end it just felt a little ick to use, like I was being lazy or something
- marsven_422 1y ago[dead]
- reynoldsbd 1y agoI’ve found that good logging/tracing discipline can play an important role here. For example, my team has a guideline to put a debug! message before blocks of code that are likely to fail. Then if something goes wrong, we can dial up the logging level and zero in on the problem fairly efficiently. With this model, we don’t find the need to use any third party error framework at all. In the abstract, we are basically treating the error as a “separate thing” from the context in which it occurred. Both are of course strongly related, however the way some of these error libraries try to squash the concepts together can be quite opinionated and doesn’t always facilitate smooth interop. Not saying this is the only way to deal with errors, but it’s just one way of thinking of the problem that I’ve had pretty good success with.
- stevefan1999 1y agoTry not to use thiserror but this instead: https://docs.rs/derive_more/latest/derive_more/ https://docs.rs/derive_more/latest/derive_more/ Reason: thiserror still requires std which greatly hinder its use for no_std context
- junon 1y agoThiserror only relies on std because primarily due to the use of the std Error type which just got stabilized into core not too long ago.
- Expurple 1y agoThiserror 2.0 (released 6 months ago) supports no_std. https://github.com/dtolnay/thiserror/releases/tag/2.0.0 https://github.com/dtolnay/thiserror/releases/tag/2.0.0