如何修复 reqwest json 解码错误?

How to fix reqwest json decode errors?

当我运行以下代码时:

use exitfailure::ExitFailure;
use reqwest::Url;
use serde_derive::{Deserialize, Serialize};
use std::env;

#[derive(Serialize, Deserialize, Debug)]
struct CompanyInfo {
    country: String,
    currency: String,
    exchange: String,
    ipo: String,
    marketCapitalization: u128,
    name: String,
    phone: String,
    shareOutstanding: f64,
    ticker: String,
    weburl: String,
    logo: String,
    finnhubIndustry: String,
}

impl CompanyInfo {
    async fn get(symbol: &String, api_key: &String) -> Result<Self, ExitFailure> {
        let url = format!(
            "https://finnhub.io/api/v1/stock/profile2?symbol={}&token={}",
            symbol, api_key
        );

        let url = Url::parse(&*url)?;
        let res = reqwest::get(url).await?.json::<CompanyInfo>().await?;

        Ok(res)
    }
}

#[tokio::main]
async fn main() -> Result<(), ExitFailure> {
    let api_key = "MY API KEY".to_string();
    let args: Vec<String> = env::args().collect();
    let mut symbol: String = "AAPL".to_string();

    if args.len() < 2 {
        println!("Since you didn't specify a company symbol, it has defaulted to AAPL.");
    } else {
        symbol = args[1].clone();
    }

    let res = CompanyInfo::get(&symbol, &api_key).await;
    println!("{:?}", res);

    Ok(())
}

我收到一个错误:Err(错误解码响应正文:第 1 行第 235 列应为“,”或“}”)。对于另一个 API,此具有类似结构的代码有效。你如何用 reqwest 解决这个问题?

通常,error decoding response body 表示您尝试反序列化给定格式的 HTTP 响应,但响应正文对该格式无效。在您的情况下,您正在尝试反序列化 JSON,因此该错误意味着您尝试反序列化的内容可能无效 JSON,或者它可能有效 JSON 但您的预期的 JSON 结构与从服务器输入的 return 结构不匹配。服务器可能在创建 JSON 时搞砸了,或者它可能 return 出于特定原因实际上不是 JSON 的响应主体(例如,某些 API 不会 return JSON 如果他们正在 return 进行 500 响应)。

为了调试和修复此问题,您需要准确了解您尝试解析的响应正文是什么样的。一种方法是将代码的解析分成两部分:一个获取文本,另一个尝试解析。例如,出于调试目的,您可以通过执行以下操作打印出您收到的响应:

// Split up the JSON decoding into two steps.
// 1.) Get the text of the body.
let response_body = reqwest::get(url).await?.text().await?;
println!("Response Body: {}", response_body);

// 2.) Parse the results as JSON.
let res: CompanyInfo = serde_json::from_str(&response_body)?;

此代码可能会像以前一样失败,但现在您将打印出失败的响应正文。到那时,您将不得不分析响应主体,这时它为什么不起作用会很明显。