diff --git a/Cargo.lock b/Cargo.lock index 939d5885..7e305113 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1259,6 +1259,7 @@ dependencies = [ "rust-embed", "serde", "serde_json", + "thiserror", "tokio", "toml", "tower-http", diff --git a/Cargo.toml b/Cargo.toml index 26a819e2..1c47037c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,4 @@ mime_guess = "2.0.4" rust-embed = { version = "8.0.0", features = ["axum-ex"] } prometheus = "0.13.3" lazy_static = "1.4.0" +thiserror = "1.0" \ No newline at end of file diff --git a/src/forward/mod.rs b/src/forward/mod.rs index ffd7f1dd..7f92ff63 100644 --- a/src/forward/mod.rs +++ b/src/forward/mod.rs @@ -14,7 +14,7 @@ use webrtc::sdp::{MediaDescription, SessionDescription}; use crate::forward::forward_internal::{get_peer_key, PeerForwardInternal}; use crate::{media, metrics}; - +use crate::HttpError; mod forward_internal; mod rtcp; mod track_match; @@ -38,11 +38,11 @@ impl PeerForward { offer: RTCSessionDescription, ) -> Result<(RTCSessionDescription, String)> { if self.internal.anchor_is_some().await { - return Err(anyhow::anyhow!("anchor is set")); + return Err(HttpError::NotFound(anyhow::anyhow!("anchor is set")).into()); } let _ = self.anchor_lock.lock().await; if self.internal.anchor_is_some().await { - return Err(anyhow::anyhow!("anchor is set")); + return Err(HttpError::NotFound(anyhow::anyhow!("anchor is set")).into()); } let peer = self .internal diff --git a/src/main.rs b/src/main.rs index 9ac52784..b3607126 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use log::info; use tower_http::services::{ServeDir, ServeFile}; use tower_http::validate_request::ValidateRequestHeaderLayer; use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; - +use thiserror::Error; use config::IceServer; use path::manager::Manager; #[cfg(not(debug_assertions))] @@ -160,7 +160,8 @@ async fn whip( return Err(anyhow::anyhow!("Content-Type must be application/sdp").into()); } let offer = RTCSessionDescription::offer(body)?; - let (answer, key) = state.paths.publish(id, offer).await?; + let (answer, key) = state.paths.publish(id, offer).await.map_err(|err|{ + AppError::not_found(anyhow::anyhow!(err))})?; Ok(Response::builder() .status(StatusCode::CREATED) .header("Content-Type", "application/sdp") @@ -184,7 +185,8 @@ async fn whep( return Err(anyhow::anyhow!("Content-Type must be application/sdp").into()); } let offer = RTCSessionDescription::offer(body)?; - let (answer, key) = state.paths.subscribe(id, offer).await?; + let (answer, key) = state.paths.subscribe(id, offer).await.map_err(|err|{ + AppError::not_found(anyhow::anyhow!(err))})?; Ok(Response::builder() .status(StatusCode::CREATED) .header("Content-Type", "application/sdp") @@ -276,11 +278,14 @@ fn string_encoder(s: &impl ToString) -> String { s[1..s.len() - 1].to_string() } -struct AppError(anyhow::Error); +pub struct AppError { + status_code: StatusCode, + error: anyhow::Error, +} impl IntoResponse for AppError { fn into_response(self) -> Response { - (StatusCode::INTERNAL_SERVER_ERROR, self.0.to_string()).into_response() + (self.status_code, self.error.to_string()).into_response() } } @@ -289,6 +294,32 @@ where E: Into, { fn from(err: E) -> Self { - Self(err.into()) + Self { + status_code: StatusCode::INTERNAL_SERVER_ERROR, + error: err.into(), + } + } +} + +impl AppError { + pub fn not_found(err: E) -> Self + where + E: Into, + { + Self { + status_code: StatusCode::NOT_FOUND, + error: err.into(), + } + } +} +#[derive(Debug, Error)] +enum HttpError { + #[error("404 not found")] + NotFound(anyhow::Error), +} + +impl IntoResponse for HttpError { + fn into_response(self) -> Response { + (StatusCode::NOT_FOUND, self.to_string()).into_response() } } diff --git a/src/path/manager.rs b/src/path/manager.rs index 243808cb..5fab833b 100644 --- a/src/path/manager.rs +++ b/src/path/manager.rs @@ -9,7 +9,7 @@ use webrtc::{ }; use crate::forward::PeerForward; - +use crate::HttpError; #[derive(Clone)] pub struct Manager { ice_servers: Vec, @@ -52,7 +52,7 @@ impl Manager { if let Some(forward) = forward { forward.add_subscribe(offer).await } else { - Err(anyhow::anyhow!("resource not exists")) + Err(HttpError::NotFound(anyhow::anyhow!("resource not exists")).into()) } }