这就是我所拥有的,但我想避免在我的reqwest值上使用unwrap
:
extern crate base64;
extern crate reqwest;
use serde_json;
use serde_json::json;
pub fn perform_get(id: String) -> serde_json::value::Value {
let client = reqwest::Client::builder().build().unwrap();
let url = String::from("SomeURL");
let res = client.get(&url).send().unwrap().text();
let mut v = json!(null);
match res {
Ok(n) => {
v = serde_json::from_str(&n).unwrap();
}
Err(r) => {
println!("Something wrong happened {:?}", r);
}
}
v
}
fn main() {
println!("Hi there! i want the function above to return a result instead of a Serde value so I can handle the error in main!");
}
Rust官方书籍The Rust Programming Language可在线免费获取。它有一个entire chapter on using Result
,解释介绍性的主题,如Result
枚举和如何使用它。
如何归还包含
Result
的serde_json::Value
?
返回任何类型的Result
都是一样的; Value
没什么特别之处:
use serde_json::json; // 1.0.38
pub fn ok_example() -> Result<serde_json::value::Value, i32> {
Ok(json! { "success" })
}
pub fn err_example() -> Result<serde_json::value::Value, i32> {
Err(42)
}
如果你有一个返回Result
的函数,你可以使用问号运算符(?
)从错误函数中提前退出,返回错误。这是避免unwrap
或expect
的简明方法:
fn use_them() -> Result<(), i32> {
let ok = ok_example()?;
println!("{:?}", ok);
let err = err_example()?;
println!("{:?}", err); // Never executed, we always exit due to the `?`
Ok(()) // Never executed
}
这只是一个基本的例子。
适用于你的MCVE,它看起来像:
use reqwest; // 0.9.10
use serde_json::Value; // 1.0.38
type Error = Box<dyn std::error::Error>;
pub fn perform_get(_id: String) -> Result<Value, Error> {
let client = reqwest::Client::builder().build()?;
let url = String::from("SomeURL");
let res = client.get(&url).send()?.text()?;
let v = serde_json::from_str(&res)?;
Ok(v)
}
在这里,我使用特征对象Box<dyn std::error::Error>
来处理任何类型的错误(非常适合快速程序和示例)。然后我在每个可能失败的方法(即返回?
)上撒上Result
,并以最终值的显式Ok
结束该函数。
请注意,使用此样式可以删除panic
和从未使用过的null
值。
也可以看看:
更好的做法,以返回
Result
也可以看看:
如果你在用户端,我建议使用Box<dyn std::error::Error>
,这允许返回实现Error
的每个类型,?
将具体的错误类型转换为动态盒装特征,这会在出现错误时添加一点开销但是当出错时不是预期或非常罕见,这不是什么大不了的事。
use reqwest;
use serde_json::value::Value;
use std::error::Error;
fn perform_get(_id: String) -> Result<Value, Box<dyn Error>> {
let client = reqwest::Client::builder().build()?;
let url = String::from("SomeURL");
let res = client.get(&url).send()?.text()?;
let v = serde_json::from_str(&res)?;
Ok(v)
// last two line could be serde_json::from_str(&res).map_err(std::convert::Into::into)
}
fn main() {
println!("{:?}", perform_get("hello".to_string()));
}
这会产生以下错误:
Err(Error { kind: Url(RelativeUrlWithoutBase), url: None })
Rust Discord的那些聪明人帮我解决了这个问题。 (用户noc)
extern crate base64;
extern crate reqwest;
pub fn get_jira_ticket() -> Result<serde_json::value::Value, reqwest::Error> {
let client = reqwest::Client::builder().build().unwrap();
let url = String::from("SomeURL");
let res = client.get(&url).send().and_then(|mut r| r.json());
res
}
fn main() {
println!("This works");
}
关键部分是在返回的标题中
-> Result<serde_json::value::Value, reqwest::Error>
而这在这里实际返回数据。
client.get(&url).send().and_then(|mut r| r.json());