@@ -205,6 +205,56 @@ pub trait Error: Debug + Display {
205205 /// assert!(request_ref::<MyLittleTeaPot>(dyn_error).is_none());
206206 /// }
207207 /// ```
208+ ///
209+ /// # Delegating Impls
210+ ///
211+ /// <div class="warning">
212+ ///
213+ /// **Warning**: We recommend implementors avoid delegating implementations of `provide` to
214+ /// source error implementations.
215+ ///
216+ /// </div>
217+ ///
218+ /// This method should expose context from the current piece of the source chain only, not from
219+ /// sources that are exposed in the chain of sources. Delegating `provide` implementations cause
220+ /// the same context to be provided by multiple errors in the chain of sources which can cause
221+ /// unintended duplication of information in error reports or require heuristics to deduplicate.
222+ ///
223+ /// In other words, the following implementation pattern for `provide` is discouraged and should
224+ /// not be used for [`Error`] types exposed in public APIs to third parties.
225+ ///
226+ /// ```rust
227+ /// # #![feature(error_generic_member_access)]
228+ /// # use core::fmt;
229+ /// # use core::error::Request;
230+ /// # #[derive(Debug)]
231+ /// struct MyError {
232+ /// source: Error,
233+ /// }
234+ /// # #[derive(Debug)]
235+ /// # struct Error;
236+ /// # impl fmt::Display for Error {
237+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238+ /// # write!(f, "Example Source Error")
239+ /// # }
240+ /// # }
241+ /// # impl fmt::Display for MyError {
242+ /// # fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243+ /// # write!(f, "Example Error")
244+ /// # }
245+ /// # }
246+ /// # impl std::error::Error for Error { }
247+ ///
248+ /// impl std::error::Error for MyError {
249+ /// fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
250+ /// Some(&self.source)
251+ /// }
252+ ///
253+ /// fn provide<'a>(&'a self, request: &mut Request<'a>) {
254+ /// self.source.provide(request) // <--- Discouraged
255+ /// }
256+ /// }
257+ /// ```
208258 #[ unstable( feature = "error_generic_member_access" , issue = "99301" ) ]
209259 #[ allow( unused_variables) ]
210260 fn provide < ' a > ( & ' a self , request : & mut Request < ' a > ) { }
0 commit comments