-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: improve error_handling exercises #772
Conversation
Also put it in the ERROR HANDLING section where it probably belongs.
Add new exercises errors5 and errors6, to introduce boxed errors and custom error enums more gently. Delete errorsn, because it tried to do too much too soon.
exercises/error_handling/errors5.rs
Outdated
CreationError::Negative => "Number is negative", | ||
CreationError::Zero => "Number is zero", |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
exercises/error_handling/errors6.rs
Outdated
PositiveNonzeroInteger::new(x) | ||
.or(Err(ParsePosNonzeroError::CreationError)) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
exercises/error_handling/errors6.rs
Outdated
// This is a custom error type that we will be using in `parse_pos_nonzero()`. | ||
#[derive(PartialEq, Debug)] | ||
enum ParsePosNonzeroError { | ||
CreationError, |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
Thanks for the review! I agree with most of your changes. I was planning to have Is there a consensus for error enum variants with payloads? I think I've seen both 1-tuple structs and structs with named fields. Are there tradeoffs involved? (I suspect there are, involving public vs private visibility of fields, but I'm not sure.)
|
I don't think there is a clear consensus. There should be no difference in field visibility since all fields in enums are pub. The main difference is how the constructor is exposed. For a struct variant it uses the constructor syntax, but for unit variants the compiler essentially adds a function with the same name for the constructor. And I think I can see where you're going with this question. enum WrappingError {
Inner(InnerError),
}
struct InnerError;
fn main() {
// The turbofish is only needed here because rustc can't infer the `T` parameter here.
// This just set's it to () so the compiler leaves me alone, most code wouldn't need this turbofish
Err::<(), _>(InnerError).map_err(WrappingError::Inner);
} This is possible with tuple variants but not with struct variants, so it will probably be easiest to teach the tuple version since it provides the needed conversion function out of the box. |
I don't understand what you mean. The ParseInt payload is internal so we don't have to worry about it, but if anything the fact that they're not all identical and they have different runtime instantiations of that type means that we really need to wrap it, if we try to replace it with our own equivalent error type we will probably provide less information than the original error did. |
Yeah, I guess you're right. Even if we can't make decisions based on those private variants, they're still relevant for display purposes. |
I hadn't realized that tuple struct constructors actually were proper functions! I thought they were special struct expression syntax that happened to look like function calls. I'm not sure this exercise is the right place to introduce that concept. Or maybe it is? It seems likely to cause confusion if it hasn't been mentioned before. |
hehe, yea. This comes up when you're re-exporting items in a library. If you a type alias to bring it in it will only import the type, but not the function, where as if you export it with a
I think you're right on this, methods are less confusing and will more naturally lead into teaching about From impls. |
Adjust error text and naming to conform with best practices. Use `map_err()` instead of `or()`. Wrap lower-level errors instead of ignoring their details. Also, don't "cheat" by bypassing the `new()` function in tests. Fix a dangling reference in the try_from_into hints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i trust your judgement @yaahc
feature: improve error_handling exercises
feature: improve error_handling exercises
Move result1 to errors4 and put it in the error handling section. Fixes #719.
Add new exercises errors5 and errors6, to introduce boxed errors and
custom error enums more gently. Delete errorsn, because it tried to do
too much too soon. Fixes #756.