This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 8454de95d feat: expose `Error::backtrace()` (#6196)
8454de95d is described below

commit 8454de95d9cfb8e7ad0193ebc0dc3b5e994d2a65
Author: xxchan <[email protected]>
AuthorDate: Tue May 20 13:21:00 2025 +0800

    feat: expose `Error::backtrace()` (#6196)
    
    * feat: expose `Error::backtrace()`
    
    Signed-off-by: xxchan <[email protected]>
    
    * fix
    
    Signed-off-by: xxchan <[email protected]>
    
    ---------
    
    Signed-off-by: xxchan <[email protected]>
---
 core/src/types/error.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/core/src/types/error.rs b/core/src/types/error.rs
index 6b1bc7a9e..26af115e0 100644
--- a/core/src/types/error.rs
+++ b/core/src/types/error.rs
@@ -417,6 +417,51 @@ impl Error {
     pub fn is_temporary(&self) -> bool {
         self.status == ErrorStatus::Temporary
     }
+
+    /// Return error's backtrace.
+    ///
+    /// Note: the standard way of exposing backtrace is the unstable feature 
[`error_generic_member_access`](https://github.com/rust-lang/rust/issues/99301).
+    /// We don't provide it as it requires nightly rust.
+    ///
+    /// If you just want to print error with backtrace, use `Debug`, like 
`format!("{err:?}")`.
+    ///
+    /// If you use nightly rust, and want to access `opendal::Error`'s 
backtrace in the standard way, you can
+    /// implement a newtype like this:
+    ///
+    /// ```ignore
+    /// // assume you already have `#![feature(error_generic_member_access)]` 
on the top of your crate
+    ///
+    /// #[derive(::std::fmt::Debug)]
+    /// pub struct OpendalError(opendal::Error);
+    ///
+    /// impl std::fmt::Display for OpendalError {
+    ///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result 
{
+    ///         self.0.fmt(f)
+    ///     }
+    /// }
+    ///
+    /// impl std::error::Error for OpendalError {
+    ///     fn provide<'a>(&'a self, request: &mut std::error::Request<'a>) {
+    ///         if let Some(bt) = self.0.backtrace() {
+    ///             request.provide_ref::<std::backtrace::Backtrace>(bt);
+    ///         }
+    ///     }
+    ///
+    ///     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+    ///         self.0.source()
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// Additionally, you can add a clippy lint to prevent usage of the 
original `opendal::Error` type.
+    /// ```toml
+    /// disallowed-types = [
+    ///     { path = "opendal::Error", reason = "Please use 
`my_crate::OpendalError` instead." },
+    /// ]
+    /// ```
+    pub fn backtrace(&self) -> Option<&Backtrace> {
+        self.backtrace.as_ref().map(|bt| bt.as_ref())
+    }
 }
 
 impl From<Error> for io::Error {

Reply via email to