debugrustMajor
Rust proper error handling (auto convert from one error type to another with question mark)
Viewed 0 times
errorautowithfrommarkpropertypeconvertrustone
Problem
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:
This code is improper; it causes a compilation error:
What is a proper pattern to deal with that case? For me,
fn get_synch_point(&self) -> Result {
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
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!!!
}Solution
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
This allow change
useful links:
Other interesting crates:
for panics:
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,
}
This allow change
io::Error to DataStoreError::Disconnect with question mark ?. Go here for detailsuseful links:
- great blog about using
thiserrorin combine withanyhow
Other interesting crates:
- 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.
for panics:
- 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.
Context
Stack Overflow Q#48430836, score: 63
Revisions (0)
No revisions yet.