Flo*_*ker 5 ownership rust serde reqwest
我正在将 a 解码reqwest::Response为 JSON。通常这工作正常,但在极少数情况下,远程服务器返回的响应不适合我struct用于反序列化的响应。在这些情况下,我想打印出原始响应文本以进行进一步调试。
但是,我在执行 JSON 反序列化和打印响应正文时遇到了麻烦。我想做的是
#[derive(serde::Deserialize)]
struct MyData {
// ...
}
async fn get_json(url: &str) -> Result<MyData, reqwest::Error> {
let response = reqwest::get(url).await?;
let text = response.text().await?;
response
.json::<MyData>().await
.map_err(|err| {
println!(
"Could not decode response from {}: {}", url, text
);
err
})
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为response.text需要self,所以我不能重复使用responsefor response.json。
基于另一个答案的代码(也在这个答案中推荐)我发现了这种方法:
let response = reqwest::get(url).await?;
let text = response.text().await?;
serde_json::from_str(&text).map_err(...)
Run Code Online (Sandbox Code Playgroud)
但是,serde_json::from_str返回 a Result<_, serde_json::Error>,因此这种方法会使我的错误处理复杂化,因为所有调用之前都返回Result<_, reqwest::Error>. 我希望我的函数也返回后者,而不是一些自定义错误包装器。
实现我的目标的惯用方法是什么?
我不认为你会逃避.text()然后serde_json::from_str(&text)分手。
但是您可以避免使用该anyhow库来定义自定义错误类型(正如 kmdreko 在他/她的评论中建议的那样)。只需使用Result<T, anyhow::Error>或等效的anyhow::Result<T>,作为任何易出错函数的返回类型。
例如(从我的代码库复制):
use anyhow::{Context, Result};
use reqwest::Client;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use url::Url;
#[derive(Debug)]
pub struct UrlPath<'a>(&'a str);
pub async fn get<T: DeserializeOwned>(
client: &Client,
backend_url: &Url,
path: &UrlPath<'_>,
) -> Result<T> {
let response = client
.get(backend_url.join(path.0).with_context(|| {
format!(
"Unable to join base URL \"{}\" with path \"{:?}\"",
backend_url, path
)
})?)
.send()
.await?;
let contents = response.text().await?;
serde_json::from_str(&contents).with_context(|| {
format!("Unable to deserialise response. Body was: \"{}\"", contents)
})
}
Run Code Online (Sandbox Code Playgroud)
这会给你一个很好的错误,如下所示:
Error: Unable to fetch Source Kinds
Caused by:
0: Unable to deserialise response. Body was: "{"detail":"Authentication credentials were not provided."}"
1: invalid type: map, expected a sequence at line 1 column 0
Run Code Online (Sandbox Code Playgroud)
with_context()fromanyhow允许您为错误提供自定义上下文。并将anywhow转换大多数错误,使它们“正常工作”。
但仅将其用于应用程序代码,您不需要告诉调用者到底出了什么问题。
更多信息: https: //docs.rs/anyhow/latest/anyhow/index.html
| 归档时间: |
|
| 查看次数: |
2602 次 |
| 最近记录: |