-
Notifications
You must be signed in to change notification settings - Fork 13.3k
The try! macro doesn't live up to its prominent position #12676
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
Comments
FWIW, the error handling section of the
For clarity, what do you mean by this? The following works fn f() -> Result<~str, Error> { ... }
fn g() -> Result<int, Error> { ... }
fn h() -> Result<f64, Error> {
try!(f());
try!(g());
// ...
Ok(3.14)
} i.e. the result type differing but the error param matching. (If the error param differs then there always needs to be some custom logic for converting them to the same type, and no generic macro can perform that.) |
It's not mentioned in the docs, but as you say, not much is on the topic, and when people ask "do I really have to use a match expr to handle IO errors?", they're either going to find You're correct, I was mistaken on the return type point, based on having read someone saying they hit issues with that rather than having tried it myself. Apologies, I've updated the list accordingly. That particular aspect is definitely not as big of an issue with that clarification. |
We do need to keep trying to improve our error handling strategy. Making |
FWIW, I have the very specific objective of being able to use a builder pattern that chains a number of methods that each return Result<MyType,Error>, and be able to use that builder pattern from "scripts" that only have a main method. I don't know of any alternative to try that allows you to chain together functions like that that return Results without repetitively unwrapping, etc. |
This issue is a little long in the tooth, and some of it has been addressed. Additionally, it would need an RFC today. (and the |
…ait-impl, r=jonas-schievink fix: Extract function from trait impl This change fixes rust-lang#10036, "Extract to function assist implements nonexistent trait methods". When we detect that the extraction is coming from within a trait impl, and that a `self` param will be necessary, we adjust which `SyntaxNode` to `insert_after`, and create a new empty `impl` block for the newly extracted function.
I've been asked to make my general concerns about
try!
more clear than what #12130 specifically focused on, so I'm going to close that issue and try to do a better job here.'try' is a short, familiar, and suggestive name. Such names are relatively rare and valuable, and would ideally be reserved for features that reach a high bar of utility and ergonomics. But the
try!
macro is, by design, a limited solution to the problem it's put up against, and its limitations are really easy to hit:try!
frommain
or the proc arg tospawn
, even though you might reasonably expect that 'passing an error up the stack' when there is no 'up the stack' would just fail.try!
for 2 different Result error types in the same fn; you have to switch to another strategy for one or split them out into separate fns.try!
for multiple calls is still verbose and repetitive.These limitations of course result from its simple implementation using
return
from a macro, and when they are brought up, solutions are easy - useunwrap
, write your own macro, just drop the result, fall back to a match expression - and the point is made thattry!
was never intended to be a general solution.But
try!
has a big footprint in the ecosystem right now. It has that valuable name. It (asif_ok!
) was the only error-handling technique directly illustrated in the "Handling I/O errors" announcement of IoResult and the removal of conditions. It's the only IO error handling macro that ships in std. It shows up frequently in example code. Regardless of the original intent, it's what people reach for first when trying to figure out how to do IO.The thing that people reach for first shouldn't have trivial headaches associated with it. The thing that shows up frequently in examples shouldn't instantly blow up when transplanted into users' first programs. Something that ships with std shouldn't require people to throw together a bunch of one-off minor variations of it in their own projects.
Or, conversely, something that has these limitations shouldn't be so visible in the ecosystem.
I don't know what the right alternative is, though I think/hope the general shape of something better would be:
I don't think wanting this basic shape amounts to wanting a silver bullet, or to trying to sweep anything under the rug, but if it's just not possible or otherwise not a good idea, I'd be interested to hear why.
The first alternative that pops to mind is a variation of Haskell's
do
notation, which other people have discussed elsewhere in more/better detail than I could. There's also thematch!
proposal on Reddit right now that may be a candidate. I'm less interested in the exact solution than in convincing the community it's a problem that should be addressed, b/c I'm sure someone else can come up with a better answer than I could.The text was updated successfully, but these errors were encountered: