feat(api): enhance error handling with serde_path_to_error integration
This commit is contained in:
47
src/api.rs
47
src/api.rs
@@ -7,8 +7,8 @@ use thiserror::Error;
|
||||
pub enum ApiError {
|
||||
#[error("HTTP request failed: {0}")]
|
||||
Request(#[from] reqwest::Error),
|
||||
#[error("Serialization error: {0}")]
|
||||
Serialization(#[from] serde_json::Error),
|
||||
#[error("Deserialization error: {0}")]
|
||||
Deserialization(#[from] serde_path_to_error::Error<serde_json::Error>),
|
||||
#[error("API error: {message}")]
|
||||
Api { message: String },
|
||||
}
|
||||
@@ -47,7 +47,31 @@ impl SonarrClient {
|
||||
}
|
||||
|
||||
let text = response.text().await?;
|
||||
serde_json::from_str(&text).map_err(ApiError::from)
|
||||
let deser = &mut serde_json::Deserializer::from_str(&text);
|
||||
|
||||
serde_path_to_error::deserialize(deser).map_err(ApiError::from)
|
||||
}
|
||||
|
||||
async fn get_debug<T: for<'de> Deserialize<'de>>(&self, endpoint: &str) -> Result<T> {
|
||||
let url = format!("{}/api/v3{}", self.base_url, endpoint);
|
||||
let response = self
|
||||
.client
|
||||
.get(&url)
|
||||
.header("X-Api-Key", &self.api_key)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(ApiError::Api {
|
||||
message: format!("HTTP {}: {}", response.status(), response.text().await?),
|
||||
});
|
||||
}
|
||||
|
||||
let text = response.text().await?;
|
||||
std::fs::write(endpoint.replace("/", "_"), &text);
|
||||
let deser = &mut serde_json::Deserializer::from_str(&text);
|
||||
|
||||
serde_path_to_error::deserialize(deser).map_err(ApiError::from)
|
||||
}
|
||||
|
||||
async fn post<T: Serialize, R: for<'de> Deserialize<'de>>(
|
||||
@@ -71,7 +95,8 @@ impl SonarrClient {
|
||||
}
|
||||
|
||||
let text = response.text().await?;
|
||||
serde_json::from_str(&text).map_err(ApiError::from)
|
||||
let deser = &mut serde_json::Deserializer::from_str(&text);
|
||||
serde_path_to_error::deserialize(deser).map_err(ApiError::from)
|
||||
}
|
||||
|
||||
pub async fn get_system_status(&self) -> Result<SystemStatus> {
|
||||
@@ -147,7 +172,7 @@ impl SonarrClient {
|
||||
}
|
||||
|
||||
pub async fn search_series(&self, term: &str) -> Result<Vec<Series>> {
|
||||
self.get(&format!(
|
||||
self.get_debug(&format!(
|
||||
"/series/lookup?term={}",
|
||||
urlencoding::encode(term)
|
||||
))
|
||||
@@ -199,7 +224,7 @@ pub struct SystemStatus {
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Series {
|
||||
pub id: u32,
|
||||
pub id: Option<u32>,
|
||||
pub title: Option<String>,
|
||||
pub alternate_titles: Option<Vec<AlternateTitle>>,
|
||||
pub sort_title: Option<String>,
|
||||
@@ -215,14 +240,14 @@ pub struct Series {
|
||||
pub original_language: Option<Language>,
|
||||
pub remote_poster: Option<String>,
|
||||
pub seasons: Option<Vec<Season>>,
|
||||
pub year: i32,
|
||||
pub year: u32,
|
||||
pub path: Option<String>,
|
||||
pub quality_profile_id: u32,
|
||||
pub season_folder: bool,
|
||||
pub monitored: bool,
|
||||
pub monitor_new_items: String,
|
||||
pub use_scene_numbering: bool,
|
||||
pub runtime: i32,
|
||||
pub runtime: u32,
|
||||
pub tvdb_id: u32,
|
||||
pub tv_rage_id: u32,
|
||||
pub tv_maze_id: u32,
|
||||
@@ -501,8 +526,8 @@ pub struct HistoryItem {
|
||||
pub quality_cutoff_not_met: bool,
|
||||
pub date: chrono::DateTime<chrono::Utc>,
|
||||
pub download_id: Option<String>,
|
||||
pub event_type: String,
|
||||
pub data: Option<HashMap<String, String>>,
|
||||
pub event_type: Option<String>,
|
||||
pub data: Option<HashMap<String, Option<String>>>,
|
||||
pub episode: Option<Episode>,
|
||||
pub series: Option<Series>,
|
||||
}
|
||||
@@ -521,7 +546,7 @@ pub struct EpisodePagingResource {
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HealthResource {
|
||||
pub id: u32,
|
||||
pub id: Option<i32>,
|
||||
pub source: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub health_type: String,
|
||||
|
||||
@@ -901,7 +901,7 @@ fn render_history_tab(f: &mut Frame, area: Rect, app: &App) {
|
||||
.as_ref()
|
||||
.map(|e| format!("S{:02}E{:02}", e.season_number, e.episode_number))
|
||||
.unwrap_or_default();
|
||||
let event = &h.event_type;
|
||||
let event = h.event_type.as_deref().unwrap_or("Unknown");
|
||||
let quality = h
|
||||
.quality
|
||||
.as_ref()
|
||||
@@ -912,7 +912,7 @@ fn render_history_tab(f: &mut Frame, area: Rect, app: &App) {
|
||||
Cell::from(date),
|
||||
Cell::from(series),
|
||||
Cell::from(episode),
|
||||
Cell::from(event.as_str()),
|
||||
Cell::from(event),
|
||||
Cell::from(quality),
|
||||
])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user