Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions library/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,52 @@ pub trait Error: Debug + Display {
/// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
/// }
/// ```
///
/// # Implementation Conventions
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this at the bottom of the existing doc comment but I wasn't sure if I should feature this more prominently, the only issue is I felt like it might be confusing to provide an example of what not to do before an example of how to use it properly, but the pre-existing example is quite long so I also worry that readers will entirely miss the new section.

///
/// <div class="warning">
///
/// **We recommend implementors avoid delegating implementations of `provide` to source error
/// implementations.**
///
/// This method should expose context from the current piece of the source chain only, not from
/// sources. Delegating `provide` implementations cause the same context to be provided by
/// multiple errors in the chain of sources which can cause unintended duplication of
/// information in error reports or require heuristics to deduplicate.
///
/// In otherwords, the following implementation pattern for `provide` is discouraged and should
/// not be used for Error types exposed in public APIs to third parties.
///
/// </div>
///
/// ```rust
/// # #![feature(error_generic_member_access)]
/// # use core::fmt;
/// # use core::error::{request_ref, Request};
/// # #[derive(Debug)]
/// struct MyError {
/// source: Error,
/// }
/// # #[derive(Debug)]
/// # struct Error;
/// # impl fmt::Display for Error {
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// # write!(f, "Example Source Error")
/// # }
/// # }
/// # impl fmt::Display for MyError {
/// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// # write!(f, "Example Error")
/// # }
/// # }
/// # impl std::error::Error for Error { }
///
/// impl std::error::Error for MyError {
/// fn provide<'a>(&'a self, request: &mut Request<'a>) {
/// self.source.provide(request)
/// }
/// }
/// ```
#[unstable(feature = "error_generic_member_access", issue = "99301")]
#[allow(unused_variables)]
fn provide<'a>(&'a self, request: &mut Request<'a>) {}
Expand Down
Loading