From 541c3613c960a569b28e58b16eb4efe6abcde50f Mon Sep 17 00:00:00 2001 From: vicrodh <103399283+vicrodh@users.noreply.github.com> Date: Tue, 14 Apr 2026 07:26:59 -0600 Subject: [PATCH] chore(api): promote release-watch API logs to info for diagnosability The debug-level log lines for status + response keys + raw body never printed at default log level, leaving zero observability on the call. Bumped to info and added body capture so a non-success status or a deserialize mismatch dumps the first 400-600 chars, which will tell us whether the endpoint returned {albums:{items:[]}}, {items:[]}, an auth error, or something else entirely. cc --- crates/qbz-qobuz/src/client.rs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/crates/qbz-qobuz/src/client.rs b/crates/qbz-qobuz/src/client.rs index 6fa40f196..b218eb02d 100644 --- a/crates/qbz-qobuz/src/client.rs +++ b/crates/qbz-qobuz/src/client.rs @@ -797,27 +797,31 @@ impl QobuzClient { .await?; let status = http_response.status(); - log::debug!( + log::info!( "[API] get_release_watch(limit={}, offset={}) status={}", limit, offset, status ); + // Capture body as text first so we can log it on unexpected shape + // regardless of JSON parse success. + let body_text = http_response.text().await?; if !status.is_success() { + log::warn!( + "[API] get_release_watch non-success body (first 400 chars): {}", + body_text.chars().take(400).collect::() + ); return Err(ApiError::ApiResponse(format!( "get_release_watch status {}", status ))); } - let response: Value = http_response.json().await?; + let response: Value = serde_json::from_str(&body_text)?; - // Log the response shape once so we can adjust the unwrap target if - // Qobuz returns something unexpected (empty follows can yield - // {albums: {items: []}} or {items: []} depending on deployment). if let Some(obj) = response.as_object() { - log::debug!( + log::info!( "[API] get_release_watch response keys: {:?}", obj.keys().collect::>() ); @@ -826,7 +830,20 @@ impl QobuzClient { // Typical Qobuz paginated album wrapper: {albums: {items, total, ...}}. // Fall back to root-level items if the server flattened it. let page_value = response.get("albums").cloned().unwrap_or(response); - Ok(serde_json::from_value(page_value)?) + match serde_json::from_value::>(page_value) { + Ok(page) => Ok(page), + Err(e) => { + log::warn!( + "[API] get_release_watch response did not match SearchResultsPage: {}. Body (first 600 chars): {}", + e, + body_text.chars().take(600).collect::() + ); + Err(ApiError::ApiResponse(format!( + "get_release_watch deserialize: {}", + e + ))) + } + } } /// Get list of genres