3 ms·
What for? What do you expect the user of your library to do with this detailed information?
by remram 4y ago
What for? What do you expect the user of your library to do with this detailed information?
- shakow 4y agoBetter understand what happened, and if/how you can fix it.
- remram 4y agoI'm not saying why have error reporting at all, I'm asking about this specific approach, for example as opposed to the article being discussed.
- shepmaster 4y ago> as opposed to the article being discussed. I'd actually say that the article and my suggestion are basically compatible. If you check out my gist [1], you'll see that I have basically the same number of user-facing types (or maybe a slightly smaller number as I merged a few structs and enums in some spots). [1]: https://gist.github.com/shepmaster/fb7f4c9519a074ea7186ca7b75afb9dd https://gist.github.com/shepmaster/fb7f4c9519a074ea7186ca7b7...
- epistasis 4y agoI would expect that the primary use is for those debugging the library. Though this could be users, it would also be developers of the library. Though, even as a library user, knowing the source of an error can be useful for working around the issue, temporarily, or maybe even figuring out that I was using the library incorrectly.
- shepmaster 4y agoThat's an interesting question that I find difficult to answer. To me, it's as if you are asking "why provide any detail about what happened?". The nonsense end result of that line of logic is that you return a single boolean that corresponds to failure/success, so I assume that's not what you mean. Contrast the two error messages: > one end of range is not a valid hexadecimal integer > the beginning of the range ("0xZZ") is not a valid hexadecimal integer The latter has more information and points the user to the general area of the problem, and probably allows them to fix the problem themselves. It could be even more improved by providing line/column information. By splitting out more and more error types (and cases), and artificially limiting yourself to using each error once, you push yourself away from "range is bad" style errors and more specific (and ideally descriptive) errors.
- remram 4y agoI'm not saying you shouldn't expose it, but why expose it as distinct error types? Why expose it as a programmatically-accessible information at all? I can see how the developer debugging the library might want it, but what is the advantage of this information being a type/enum/... over the same information in a string, if the only purpose is for a developer to read it?
- orf 4y agoIt fits better with the language. It doesn’t cost much (anything?) and in simple cases (errors with no dependent fields) returning it is akin to returning an error code.
- shepmaster 4y ago> Why expose it I read "expose" in two possible ways: (1) as a public- / user-facing API (2) existing at all. When an error type is a public API that is bound by semver, I do think you should be very careful about what you expose. I suggest starting with an opaque [1] error type and only exposing exactly what you are comfortable with supporting. That may boil down to basically only a string (a.k.a. the `Error` trait). > Why expose it as a programmatically-accessible information at all? A few things come to mind... I'm a huge fan in testing my error cases as much as possible. To that end, a bunch of my tests are semantically `assert_matches!(Err(MyError::Case { .. }), function_result_value)`. Not all errors are equivalent. For example, if my library fails to read a configuration file, perhaps the caller of the library can recover from that by downloading a file. However, this requires the caller to be able to tell what caused the error. Interacting with an external API, such as HTTP status or command line exit codes. In this case, you can categorize your errors into domains like "server error" / "client error" / "authorization error". These could all be done by string matching, but that tends to be comparatively brittle. > the same information in a string Aggregating strings like that requires dynamic allocation, which isn't universally available in Rust programs. For example, SNAFU works fine in a `no_std` environment and I know that it's been used in cases like embedded and Windows kernel drivers. > if the only purpose is for a developer to read it I don't think that's always true. [1]: https://docs.rs/snafu/latest/snafu/guide/opaque/index.html https://docs.rs/snafu/latest/snafu/guide/opaque/index.html