【问题标题】:How can I bubble up an underlying error type from a custom error type?如何从自定义错误类型中冒出底层错误类型?
【发布时间】:2020-09-18 18:17:06
【问题描述】:

我有一个自定义错误,我用它来包装几个标准的 Rust 错误,如下所示:

#[derive(Debug)]
pub struct MyError {
    details: String,
}

impl MyError {
    fn new(msg: &str) -> MyError {
        dbg!(msg);
        MyError {
            details: msg.to_string(),
        }
    }
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.details)
    }
}

impl From<std::io::Error> for MyError {
    fn from(err: std::io::Error) -> Self {
        MyError::new(&err.to_string())
    }
}

impl From<std::string::FromUtf8Error> for MyError {
    fn from(err: std::string::FromUtf8Error) -> Self {
        MyError::new(&err.to_string())
    }
}

现在,我只是将错误消息冒泡到我的 MyError 中。但是,我还想创建一个返回底层错误类型的方法,以便我可以在稍后的时间点将其与 Enum 或其他内容匹配。如何将新方法添加到输出基础错误类型的错误中?我看到 Error.kind() 可能是我正在寻找的东西,但我无法让它工作。

【问题讨论】:

  • 你为什么不让MyError 一个枚举不同类型的错误呢? enum MyError { Utf8(std::string::FromUtf8Error), Io(std::io::Error) }
  • 你可能还想看看Any trait。 doc.rust-lang.org/std/any/index.html您的错误类型可能是Box&lt;dyn Error + Any&gt;

标签: rust


【解决方案1】:

这是我在 cmets 中提到的实现,下面是你将如何使用它并匹配它:Playground

use std::fmt;

#[derive(Debug)]
pub enum MyError {
    FromUtf8(std::string::FromUtf8Error),
    Io(std::io::Error),
    Generic(String),
}

impl MyError {
    fn new(msg: &str) -> Self {
        dbg!(msg);
        MyError::Generic(msg.to_string())
    }
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use MyError::*;
        match self {
            FromUtf8(e) => write!(f, "{}", e),
            Io(e) => write!(f, "{}", e),
            Generic(e) => write!(f, "{}", e),
        }
    }
}

impl From<std::io::Error> for MyError {
    fn from(err: std::io::Error) -> Self {
        MyError::Io(err)
    }
}

impl From<std::string::FromUtf8Error> for MyError {
    fn from(err: std::string::FromUtf8Error) -> Self {
        MyError::FromUtf8(err)
    }
}

fn main() {
    let e1 = MyError::new("Oops");
    println!("{}", e1);
    use MyError::*;
    match e1 {
        FromUtf8(e) => println!("UTF8 error"),
        Io(e) => println!("IO error"),
        Generic(e) => println!("Just an error"),
    }
}

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多