failure
failure copied to clipboard
[WIP] Failure 0.2
Hi! This PR introduces a few of the things I've talked about in #287, namely:
- [x] Compile on the 2018 Edition
- [x] Rename
#[derive(Fail)]
to#[derive(Error)]
- [x] Rename
failure::Error
tofailure::DefaultError
Still needed:
- [ ] Review all documentation for accuracy
- [ ] Compile without warnings, especially in the
AsFail for Fail
definition. - [ ] Rename
Fail
toErrorExt
- [ ] Change the derive to work on
std::error::Error
, pending backtrace support instd
. This might need to wait until Failure 0.3, however—I haven't thought through the ramifications of that breaking change.
Feedback, help and contributions are welcome!
Brought up a point about the naming of DefaultError
: https://github.com/rust-lang-nursery/failure/issues/287#issuecomment-455953345
This might be a bit radical but I believe we should name failure
s error type, error
.
🌏 I imagine a world where Rust has a primitive error type, named error
(in line with other primitives like bool
) that would replace it (and start defaulting the E type argument of Result
).
A thought .. why is there a name change being considered for failure::Error
? There isn't a name conflict between failure::Error
the derive and failure::Error
the struct.
Not saying I don't want a name change, just curious why it was added to the opening.
I'll reproduce @yoshuawuyts' comment here:
@davidbarsky If error handling is expressed as a graph, I currently use Failure's Fail trait to define "leaf node" errors, and Failure's Error struct to define "parent node" errors. Failure's Error struct essentially fills a similar role as Box<std::error::Error + Sync + Send> would do using just stdlib. I don't feel the name DefaultError maps well to this use. I think it's because it's perfectly possible to create a specialized error type in one place, only for it to be converted back into the default later on. Reverting back to a "default" feels kind of odd. For example: I think something like BoxedError, GenericError, or AnyError might hit closer to the mark (though ideally less verbose / not using already meaningful terms). I think it'd be nice if we could find a name that worked well for all uses.
I didn't think of that use-case, but you do raise a good point. I'd be happy to discuss these names, but initially, I am a fan of AnyError
.
@mehcode:
This might be a bit radical but I believe we should name failures error type, error. 🌏 I imagine a world where Rust has a primitive error type, named error (in line with other primitives like bool) that would replace it (and start defaulting the E type argument of Result).
I think you might be onto something there, but I'm in no way qualified to make that decision alone. How you would you feel about introducing failure::Error
into std as std::Error
at some distant point in the future? I think the long-term goal of Failure should be to obsolete itself/merge itself into the standard library.
A thought .. why is there a name change being considered for failure::Error ? There isn't a name conflict between failure::Error the derive and failure::Error the struct.
Failure's derive is exported as Error
and Failure has a struct called Error
. While they may not technically conflict, it might be a confusing to refer to failure::Error
“the derive” and failure::Error
“the struct”. The primitive-like option of failure::error
is a clever workaround, though.
@davidbarsky yay, glad you found it helpful!
By the way, I really like your idea of perhaps getting most of Failure's bits into stdlib. I think it'd be cool if every version of failure could move more into stdlib, until all we hit a ceiling.
Coincidentally, have you considered writing about Failure's 0.2 design? Back in 2017 Boats wrote a post introducing failure. I think it'd be cool if there'd be something similar for the 0.2 changes; perhaps that could help people understand the changes in stdlib, and which role failure now plays :sparkles:
Coincidentally, have you considered writing about Failure's 0.2 design? Back in 2017 Boats wrote a post introducing failure. I think it'd be cool if there'd be something similar for the 0.2 changes; perhaps that could help people understand the changes in stdlib, and which role failure now plays ✨
I think that's a good idea! I tried to cover that via #287, but I think a blog post is a good idea. First things first, I'll need to create a blog.
I see failure
as forever providing:
- Error derives. Library authors will want custom error types and helping to make this use case simple is a good but polarizing goal (which makes it a great fit for a crate and not so great for std).
- Error extension traits. See
ResultExt
. - Simple error construction. See
err_msg
. - Error macros. See
bail!
, andformat_err!
I see std
as providing both an error
type and a std::error
module (just like it does for str
and std::str
).
The type itself can be completely opaque and just implement some important traits like Error
and From<T> where T: Error
. The type could be implemented exactly as it is in failure
today. In some far future where we have anonymous enumerations, perhaps it can be implemented using that. I have no preference on implementation.
In doing so you get the magical ability of being able to default Result
s E type to error
. Library authors can continue to use custom error types with good reason. Application authors can use .downcast
on error
to figure out what error they got if needed.
I do plan to write up an RFC for this but am waiting for the 2019 roadmap and some 2018 stuff to shake out (e.g., await) so mind share is available.
Naming: AnyError
is descriptive. Personally, I like the name Flare
for this type (what I've been using) as its short and definitely unique. I assume we are also wanting to avoid the (failure::
)Error
name which becomes more awkward in code, with closer integration of std::error::Error
.
I think ChainedError
or ErrorChain
or LinkedError
are other good names. I would love to see some progress and decision on this PR.