我想学习如何正确处理 rust 迹中的错误.我读过bookthis example;现在我想知道我应该如何处理这个函数中的错误:

fn get_synch_point(&self) -> Result<pv::synch::MeasPeriods, reqwest::Error> {
    let url = self.root.join("/term/pv/synch"); // self.root is url::Url
    let url = match url {
        Ok(url) => url,
        // ** this err here is url::ParseError and can be converted to Error::Kind https://docs.rs/reqwest/0.8.3/src/reqwest/error.rs.html#54-57 **//
        Err(err) => {
            return Err(Error {
                kind: ::std::convert::From::from(err),
                url: url.ok(),
            })
        }
    };

    Ok(reqwest::get(url)?.json()?) //this return reqwest::Error or convert to pv::sych::MeasPeriods automaticly
}      

这个代码是不正确的;它会导致编译错误:

error[E0451]: field `kind` of struct `reqwest::Error` is private
  --> src/main.rs:34:42
   |
34 |             Err(err) => return Err(Error{kind: ::std::convert::From::from(err), url: url.ok()})
   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `kind` is private

error[E0451]: field `url` of struct `reqwest::Error` is private
  --> src/main.rs:34:81
   |
34 |             Err(err) => return Err(Error{kind: ::std::convert::From::from(err), url: url.ok()})
   |                                                                                 ^^^^^^^^^^^^^ field `url` is private

什么是处理该案件的适当模式?对我来说,reqwest::Error在这种情况下是一个很好的解决方案,所以我希望避免定义自己的错误类型:

enum MyError {
    Request(reqwest::Error),
    Url(url::ParseError) // this already a part of request::Error::Kind!!!
} 

推荐答案

2020年更新

rust编程语言正在快速发展,因此可以添加新的答案!我真的很喜欢custom_error,但现在我想thiserror将是我最爱的人!

use thiserror::Error;

#[derive(Error, Debug)]
pub enum DataStoreError {
    #[error("data store disconnected")]
    Disconnect(#[from] io::Error),
    #[error("the data for key `{0}` is not available")]
    Redaction(String),
    #[error("invalid header (expected {expected:?}, found {found:?})")]
    InvalidHeader {
        expected: String,
        found: String,
    },
    #[error("unknown data store error")]
    Unknown,
}

这允许将io::Error更改为带有问号?DataStoreError::Disconnect.在这里买details美元

有用的链接:


其他有趣的 crate :

  • anyhow-基于std::Error::Error构建的灵活具体错误类型
  • snafu-正常情况:所有问题都已解决-SNAFU是一个库,可以在添加上下文时轻松地将潜在错误分配到特定于域的错误中.(类似于此错误)
  • custom_error-这个 crate 包含一个macro,它应该可以更容易地定义自定义错误,而无需编写大量样板代码.

对于panic :

  • proc-macro-error-此 crate 旨在使proc宏中的错误报告简单易用.
  • human-panic-人类的panic 信息.通过调用std::panic::set_hook来处理panic ,从而使错误对人类有利.

Rust相关问答推荐

如何在Rust中为具有多个数据持有者的enum变体编写文档 comments ?

如何处理动态 struct 实例化?

如何从铁 rust 中呼唤_mm_256_mul_ph?

Rust:跨多个线程使用hashmap Arc和rwlock

关于如何初始化弱 struct 字段的语法问题

如何为 struct 字段设置新值并在Ruust中的可变方法中返回旧值

为什么';t std::cell::ref使用引用而不是非空?

写入引用会更新基础值,但引用会打印意外的值

将Vec<;U8&>转换为Vec<;{Float}&>

如何初始化选项<;T>;数组Rust 了?

我应该如何表达具有生命周期参数的类型的总排序,同时允许与不同生命周期进行比较?

要求类型参数有特定的大小?

为什么 js_sys Promise::new 需要 FnMut?

需要哪些编译器优化来优化此递归调用?

在描述棋盘时如何最好地使用特征与枚举

如何将 &[T] 或 Vec<T> 转换为 Arc<Mutex<[T]>>?

一个函数调用会产生双重borrow 错误,而另一个则不会

如何将这些测试放在一个单独的文件中?

在运行时在 Rust 中加载字体

切片不能被 `usize` 索引?