本文介绍了Rust 正确的错误处理(自动从一种错误类型转换为另一种带有问号的错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想学习如何正确处理 Rust 中的错误.我已阅读这个例子;现在我想知道我应该如何处理这个函数中的错误:

I want to learn how to properly deal with errors in Rust. I have read the book and this example; now I would like to know how I should deal with errors in this function:

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
}

此代码不正确;它会导致编译错误:

This code is improper; it causes a compilation error:

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 在这种情况下是一个很好的解决方案,所以我想避免定义自己的错误类型:

What is a proper pattern to deal with that case? For me, reqwest::Error in this case is a good solution so I would like to avoid defining my own error type:

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

推荐答案

2020 年更新

Rust 编程语言发展迅速,因此可以添加新的答案!我真的很喜欢 custom_error 但现在我觉得 thiserror 将是我所爱的人!

Update 2020

The rust programming language is evolving quickly so a new answer can be added! I really liked custom_error but now I think thiserror will be my loved one!

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.去这里查看详细信息

This allow change io::Error to DataStoreError::Disconnect with question mark ?. Go here for details

有用的链接:

  • great blog about using thiserror in combine with anyhow
  • anyhow - 基于 std::error::Error 构建的灵活的具体错误类型
  • snafu - 情况正常:全部搞砸 - SNAFU 是一个可以轻松将底层错误分配到域中的库- 添加上下文时的特定错误.(类似于这个错误)
  • custom_error - 此 crate 包含一个,应该可以更容易地无需编写大量样板代码即可定义自定义错误.
  • anyhow - Flexible concrete Error type built on std::error::Error
  • snafu - Situation Normal: All Fouled Up - SNAFU is a library to easily assign underlying errors into domain-specific errors while adding context. (similar to thiserror)
  • custom_error - This crate contains a macro that should make it easier to define custom errors without having to write a lot of boilerplate code.
  • proc-macro-error - 这个 crate 旨在在 proc- 中进行错误报告宏简单易用.
  • human-panic - 人类恐慌信息.通过调用 std::panic::set_hook 处理恐慌,使错误对人类有益.
  • proc-macro-error - This crate aims to make error reporting in proc-macros simple and easy to use.
  • human-panic - Panic messages for humans. Handles panics by calling std::panic::set_hook to make errors nice for humans.

这篇关于Rust 正确的错误处理(自动从一种错误类型转换为另一种带有问号的错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 04:32