failure icon indicating copy to clipboard operation
failure copied to clipboard

[WIP] Failure 0.2

Open davidbarsky opened this issue 6 years ago • 8 comments

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 to failure::DefaultError

Still needed:

  • [ ] Review all documentation for accuracy
  • [ ] Compile without warnings, especially in the AsFail for Fail definition.
  • [ ] Rename Fail to ErrorExt
  • [ ] Change the derive to work on std::error::Error, pending backtrace support in std. 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!

davidbarsky avatar Jan 20 '19 17:01 davidbarsky

Brought up a point about the naming of DefaultError: https://github.com/rust-lang-nursery/failure/issues/287#issuecomment-455953345

yoshuawuyts avatar Jan 21 '19 05:01 yoshuawuyts

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).


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.

mehcode avatar Jan 21 '19 05:01 mehcode

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 avatar Jan 21 '19 15:01 davidbarsky

@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:

yoshuawuyts avatar Jan 21 '19 16:01 yoshuawuyts

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.

davidbarsky avatar Jan 21 '19 16:01 davidbarsky

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!, and format_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 Results 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.

mehcode avatar Jan 21 '19 16:01 mehcode

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.

dekellum avatar Jan 21 '19 18:01 dekellum

I think ChainedError or ErrorChain or LinkedError are other good names. I would love to see some progress and decision on this PR.

mmrath avatar Mar 01 '19 07:03 mmrath