Giter Site home page Giter Site logo

Comments (8)

chungwong avatar chungwong commented on August 11, 2024

Just like the backtrace member, it should be enabled only when both std and backtrace features are enabled, as it would be bringing non-trivial cost to the unhappy path.

Does it mean this feature will not work on branch no_std? That is, running the no_std version of onoff_light will not have a nice error report.

from rs-matter.

ivmarkov avatar ivmarkov commented on August 11, 2024

It will work on branch no_std. "std" is enabled on that branch by default as well.

from rs-matter.

chungwong avatar chungwong commented on August 11, 2024

It will work on branch no_std. "std" is enabled on that branch by default as well.

Oh, I think I am confused. So the no_std branch is not actually no std(It does use the std library conditionally)

Given no_std branch has the std feature enabled by default, does it mean to be really no_std, it is necessary to turn off the std feature manually?

from rs-matter.

ivmarkov avatar ivmarkov commented on August 11, 2024

Yeah. I don't see a big deal here. This is a standard pattern for a bunch of no_std-compatible crates.

from rs-matter.

ssnover avatar ssnover commented on August 11, 2024

@ivmarkov what are your thoughts on an API like this to resolve this issue?

pub struct Error {
    code: ErrorCode,
    #[cfg(all(feature = "std", feature = "backtrace"))]
    backtrace: std::backtrace::Backtrace,
    #[cfg(feature = "std")]
    inner: Option<Box<dyn std::error::Error>>,
}

impl Error {
    pub fn new(code: ErrorCode) -> Self {
        Self {
            code,
            #[cfg(all(feature = "std", feature = "backtrace"))]
            backtrace: std::backtrace::Backtrace::capture(),
            #[cfg(feature = "std")]
            inner: None,
        }
    }

    #[cfg(feature = "std")]
    pub fn new_with_details(code: ErrorCode, detailed_err: Box<dyn std::error::Error>) -> Self {
        Self {
            code,
            #[cfg(all(feature = "std", feature = "backtrace"))]
            backtrace: std::backtrace::Backtrace::capture(),
            #[cfg(feature = "std")]
            inner: Some(detailed_err),
        }
    }

    #[cfg(feature = "std")]
    pub fn details(&self) -> Option<&dyn std::error::Error> {
        self.inner.as_ref().map(|err| err.as_ref())
    }
} // impl Error

#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        // Keep things simple for now
        Self::new_with_details(ErrorCode::StdIoError, Box::new(e))
    }
}

I would implement the above for any error type which implements std::error::Error but leave the current new method for no_std use cases where it might not be implemented for the concrete error type.

from rs-matter.

ssnover avatar ssnover commented on August 11, 2024

With the above, I get a log like this:

[2023-08-17T23:57:44Z WARN  on_off_light] mDNS exited: Os { code: 98, kind: AddrInUse, message: "Address already in use" }

Generated by:

res = mdns_runner => {
    log::warn!("mDNS exited: {:?}", res.unwrap_err().details().unwrap());
},

from rs-matter.

ivmarkov avatar ivmarkov commented on August 11, 2024

With the above, I get a log like this:

[2023-08-17T23:57:44Z WARN  on_off_light] mDNS exited: Os { code: 98, kind: AddrInUse, message: "Address already in use" }

Generated by:

res = mdns_runner => {
    log::warn!("mDNS exited: {:?}", res.unwrap_err().details().unwrap());
},

Would work, however I would also suggest:

#[cfg(all(feature = "std", feature = "backtrace"))]
inner: Option<Box<dyn std::error::Error>>,

I.e. the Error member should be protected with the backtrace feature in addition to std as its collection is non-trivial and needs allocations.

Additionally:

  • The fmt::Display implementation of Error should be extended - when std and backtrace are enabled - to display the error message from the dyn std::error::Error so that you don't have to reach out to res.unwrap_err().details() every time
  • The fmt::Debug implementation of Error should also be extended to capture the backtrace - if it exists - from the dyn std::error::Error - if possible. Not sure if this is possible with Rust stable as of yet and if the std::error::Error captures a backtrace

from rs-matter.

ivmarkov avatar ivmarkov commented on August 11, 2024

Closing, because this is implemented since quite some time...

from rs-matter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.