audio streaming app plyr.fm
38
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 8c2cf0cc028d7113c0ee4cf893ecf4c9ba8cca4d 84 lines 2.5 kB view raw
1//! Application state and error types. 2 3use std::sync::Arc; 4 5use axum::{ 6 http::StatusCode, 7 response::{IntoResponse, Response}, 8 Json, 9}; 10use tokio::sync::broadcast; 11use tracing::error; 12 13use crate::claude::ClaudeClient; 14use crate::db::LabelDb; 15use crate::labels::{Label, LabelError, LabelSigner}; 16 17/// Shared application state. 18#[derive(Clone)] 19pub struct AppState { 20 pub audd_api_token: String, 21 pub audd_api_url: String, 22 pub db: Option<Arc<LabelDb>>, 23 pub signer: Option<Arc<LabelSigner>>, 24 pub label_tx: Option<broadcast::Sender<(i64, Label)>>, 25 /// Claude client for image moderation (if configured) 26 pub claude: Option<Arc<ClaudeClient>>, 27} 28 29/// Application error type. 30#[derive(Debug, thiserror::Error)] 31pub enum AppError { 32 #[error("audd error: {0}")] 33 Audd(String), 34 35 #[error("claude error: {0}")] 36 Claude(String), 37 38 #[error("image moderation not configured")] 39 ImageModerationNotConfigured, 40 41 #[error("labeler not configured")] 42 LabelerNotConfigured, 43 44 #[error("bad request: {0}")] 45 BadRequest(String), 46 47 #[error("not found: {0}")] 48 NotFound(String), 49 50 #[error("label error: {0}")] 51 Label(#[from] LabelError), 52 53 #[error("database error: {0}")] 54 Database(#[from] sqlx::Error), 55 56 #[error("io error: {0}")] 57 Io(#[from] std::io::Error), 58} 59 60impl IntoResponse for AppError { 61 fn into_response(self) -> Response { 62 error!(error = %self, "request failed"); 63 let (status, error_type) = match &self { 64 AppError::Audd(_) => (StatusCode::BAD_GATEWAY, "AuddError"), 65 AppError::Claude(_) => (StatusCode::BAD_GATEWAY, "ClaudeError"), 66 AppError::ImageModerationNotConfigured => { 67 (StatusCode::SERVICE_UNAVAILABLE, "ImageModerationNotConfigured") 68 } 69 AppError::LabelerNotConfigured => { 70 (StatusCode::SERVICE_UNAVAILABLE, "LabelerNotConfigured") 71 } 72 AppError::BadRequest(_) => (StatusCode::BAD_REQUEST, "BadRequest"), 73 AppError::NotFound(_) => (StatusCode::NOT_FOUND, "NotFound"), 74 AppError::Label(_) => (StatusCode::INTERNAL_SERVER_ERROR, "LabelError"), 75 AppError::Database(_) => (StatusCode::INTERNAL_SERVER_ERROR, "DatabaseError"), 76 AppError::Io(_) => (StatusCode::INTERNAL_SERVER_ERROR, "IoError"), 77 }; 78 let body = serde_json::json!({ 79 "error": error_type, 80 "message": self.to_string() 81 }); 82 (status, Json(body)).into_response() 83 } 84}