diff --git a/Cargo.lock b/Cargo.lock index 1cd060b..183abb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -726,6 +726,7 @@ dependencies = [ "serde_json", "thiserror", "tokio", + "tracing", ] [[package]] @@ -1291,9 +1292,21 @@ checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.34" diff --git a/Cargo.toml b/Cargo.toml index a13c63c..b20798f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ serde_json = "1" chrono = "0.4" quick-xml = "0.38" thiserror = "2" +tracing = "0.1" diff --git a/src/lib.rs b/src/lib.rs index bd894e1..8a27f13 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ use serde_json::Value; use std::sync::Arc; use thiserror::Error; use tokio::{net::TcpListener, sync::RwLock}; +use tracing::warn; pub async fn start( title: String, @@ -26,10 +27,15 @@ pub async fn start( } #[derive(Error, Debug)] -enum FetchError {} +enum FetchError { + #[error("error fetching url")] + Fetching(reqwest::Error), + #[error("error parsing json")] + JsonParsing(reqwest::Error), +} trait Feed { - async fn fetch(&mut self) -> Result<(), Box>; + async fn fetch(&mut self) -> Result<(), FetchError>; } #[cfg(test)] @@ -69,7 +75,7 @@ impl rss::ToRss for TestFeed { #[cfg(test)] impl Feed for TestFeed { - async fn fetch(&mut self) -> Result<(), Box> { + async fn fetch(&mut self) -> Result<(), FetchError> { self.amount_fetch_calls += 1; Ok(()) } @@ -84,7 +90,7 @@ struct LiveFeed { } impl Feed for LiveFeed { - async fn fetch(&mut self) -> Result<(), Box> { + async fn fetch(&mut self) -> Result<(), FetchError> { let broadcasts = self.get_all_broadcasts().await?; for broadcast in broadcasts { @@ -132,12 +138,17 @@ impl LiveFeed { self.episodes.iter().any(|e| e.url == url) } - async fn get_all_broadcasts(&self) -> Result, Box> { + async fn get_all_broadcasts(&self) -> Result, FetchError> { // List of broadcasts: https://audioapi.orf.at/oe1/api/json/current/broadcasts // // ^ contains link, e.g. https://audioapi.orf.at/oe1/api/json/4.0/broadcast/797577/20250611 let url = "https://audioapi.orf.at/oe1/api/json/current/broadcasts"; - let data: Value = reqwest::get(url).await?.json().await?; + let data: Value = reqwest::get(url) + .await + .map_err(FetchError::Fetching)? + .json() + .await + .map_err(FetchError::JsonParsing)?; let mut ret: Vec = Vec::new(); @@ -145,13 +156,19 @@ impl LiveFeed { for day in days { if let Some(broadcasts) = day["broadcasts"].as_array() { for broadcast in broadcasts { + let Some(title) = broadcast["title"].as_str() else { + warn!("Broadcast has no 'title' attribute, skipping broadcast"); + continue; + }; + let Some(href) = broadcast["href"].as_str() else { + warn!("Broadcast has no 'href' attribute, skipping broadcast"); + continue; + }; if self.filter_titles.is_empty() - || self - .filter_titles - .contains(&broadcast["title"].as_str().unwrap().into()) + || self.filter_titles.contains(&title.into()) { { - ret.push(broadcast["href"].as_str().unwrap().into()); + ret.push(href.into()); } } } diff --git a/src/web.rs b/src/web.rs index 076b611..9fdcf74 100644 --- a/src/web.rs +++ b/src/web.rs @@ -4,7 +4,9 @@ use reqwest::header; use std::sync::Arc; use tokio::{net::TcpListener, sync::RwLock}; -async fn stream_handler(State(state): State>>) -> impl IntoResponse { +async fn stream_handler( + State(state): State>>, +) -> impl IntoResponse { state.write().await.fetch().await.unwrap(); let content = state.read().await.to_rss();