improved error messages
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
bb33d3b015
commit
10c5cb88db
|
@ -3,4 +3,5 @@
|
|||
## cli
|
||||
- optimized listing by not searching on the client but on the server
|
||||
- categories now shown with name instead of just ID
|
||||
- improved API response deserialize error messages
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ anyhow = "1.0.34"
|
|||
clap = "2.33.3"
|
||||
env_logger = "0.8.2"
|
||||
fuzzy-matcher = "0.3.7"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.11"
|
||||
once_cell = "1.5.2"
|
||||
opener = "0.4.1"
|
||||
|
@ -24,7 +25,7 @@ serde_json = "1.0.60"
|
|||
structopt = "0.3.21"
|
||||
term-table = "1.3.0"
|
||||
term_size = "0.3.2"
|
||||
thiserror = "1.0.23"
|
||||
tokio = { version = "0.2.23", features = ["macros", "fs", "process"] }
|
||||
url = "2.2.0"
|
||||
lazy_static = "1.4.0"
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ pub async fn run(
|
|||
.await?;
|
||||
|
||||
let status = res.status();
|
||||
let res = serde_json::from_slice::<UpResp>(&res.bytes().await?)?;
|
||||
let res = util::api::try_deserialize_api_reponse::<UpResp>(&res.bytes().await?)?;
|
||||
|
||||
println!("Server responded with code {}", status);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ pub mod api {
|
|||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
// cached api responses
|
||||
|
@ -46,6 +47,14 @@ pub mod api {
|
|||
Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("Error Deserializing JSON api response: \n{json}\nError: {error}")]
|
||||
pub struct ApiDeserializeError {
|
||||
pub json: String,
|
||||
#[source]
|
||||
pub error: serde_json::Error,
|
||||
}
|
||||
|
||||
pub async fn cats(http: &Client) -> Result<&Vec<Category>> {
|
||||
Ok(init_once_cell!(CATS, {
|
||||
info!("Requesting categories from server");
|
||||
|
@ -53,7 +62,7 @@ pub mod api {
|
|||
.get("https://data.tilera.xyz/api/jensmemes/categories")
|
||||
.send()
|
||||
.await?;
|
||||
let cats = serde_json::from_slice::<CatsResp>(&res.bytes().await?)?;
|
||||
let cats = try_deserialize_api_reponse::<CatsResp>(&res.bytes().await?)?;
|
||||
cats.categories.into_iter().collect()
|
||||
}))
|
||||
}
|
||||
|
@ -84,7 +93,7 @@ pub mod api {
|
|||
|
||||
info!("Requesting memes from server");
|
||||
let res = http.get(url).send().await?;
|
||||
let memes = serde_json::from_slice::<MemesResp>(&res.bytes().await?)?;
|
||||
let memes = try_deserialize_api_reponse::<MemesResp>(&res.bytes().await?)?;
|
||||
|
||||
Ok(MEMES
|
||||
.lock()
|
||||
|
@ -101,10 +110,41 @@ pub mod api {
|
|||
.get("https://data.tilera.xyz/api/jensmemes/users")
|
||||
.send()
|
||||
.await?;
|
||||
let users = serde_json::from_slice::<UsersResp>(&res.bytes().await?)?;
|
||||
let users = try_deserialize_api_reponse::<UsersResp>(&res.bytes().await?)?;
|
||||
users.users
|
||||
}))
|
||||
}
|
||||
|
||||
/// tries to deserialize `json` as `T`, and if it fails converts the error
|
||||
/// to a `ApiDeserializeError`
|
||||
pub fn try_deserialize_api_reponse<'a, T: serde::Deserialize<'a>>(json: &'a [u8]) -> Result<T> {
|
||||
let result = serde_json::from_slice::<T>(&json);
|
||||
result.map_err(|error| match std::str::from_utf8(json) {
|
||||
Err(e) => e.into(),
|
||||
Ok(json) => ApiDeserializeError {
|
||||
json: json.into(),
|
||||
error,
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn api_deserialize_error() {
|
||||
let incorrect_json = r#"
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
"#;
|
||||
|
||||
let result = try_deserialize_api_reponse::<UsersResp>(incorrect_json.as_bytes());
|
||||
println!("{}", result.unwrap_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn open_link(url: &str) -> anyhow::Result<()> {
|
||||
|
|
Loading…
Reference in New Issue