diff --git a/Cargo.lock b/Cargo.lock index f99becd..435d90a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,6 +357,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "serde_path_to_error", "serde_repr", "serde_with", "thiserror 2.0.3", @@ -1233,6 +1234,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.19" diff --git a/edu-ws/Cargo.toml b/edu-ws/Cargo.toml index 9e3806b..67c7a63 100644 --- a/edu-ws/Cargo.toml +++ b/edu-ws/Cargo.toml @@ -16,6 +16,7 @@ html-escape = "0.2" reqwest = { version = "0.12", default-features = false, features = ["json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +serde_path_to_error = "0.1" serde_repr = "0.1" serde_with = "3" thiserror = "2" diff --git a/edu-ws/src/ws.rs b/edu-ws/src/ws.rs index 1fb0026..9de6486 100644 --- a/edu-ws/src/ws.rs +++ b/edu-ws/src/ws.rs @@ -10,7 +10,7 @@ use url::Url; use crate::{ response::{content::Section, course::Course, info::Info}, - serde::{NumBool, UntaggedResultHelper}, + serde::NumBool, token::Token, }; @@ -35,7 +35,7 @@ pub enum RequestError { #[error(transparent)] HttpError(#[from] reqwest::Error), #[error(transparent)] - Decode(#[from] serde_json::Error), + Decode(#[from] serde_path_to_error::Error), } impl RequestError { @@ -121,13 +121,23 @@ impl Client { .text() .await .unwrap(); - - let ret = serde_json::from_str::<'_, UntaggedResultHelper>(&response) - .inspect(|_| debug!(response)) - .inspect_err(|err| error!(?err, response, "Could not deserialize response"))? - .0?; - - Ok(ret) + debug!(response); + + let de = &mut serde_json::Deserializer::from_str(&response); + let ok_err = match serde_path_to_error::deserialize(de) { + Ok(value) => return Ok(value), + Err(err) => err, + }; + + let de = &mut serde_json::Deserializer::from_str(&response); + match serde_path_to_error::deserialize(de) { + Ok(value) => Err(RequestError::WsError(value)), + Err(err) => { + error!(%ok_err, "Could not deserialize response"); + error!(%err, "Could not deserialize error"); + Err(RequestError::Decode(ok_err)) + } + } } pub async fn get_info(&self) -> Result {