diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/errors.rs | 27 | ||||
-rw-r--r-- | src/main.rs | 64 |
2 files changed, 89 insertions, 2 deletions
diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..70b1a43 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,27 @@ +use axum::{response::{Response, IntoResponse}, body::{boxed, self}}; +use hyper::StatusCode; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ServiceError { + #[error("Solarlib error: {0}")] + Solarlib(#[from] solarlib::errors::Error), + + #[error("Axum error: {0}")] + Axum(#[from] axum::Error), +} + +pub type StringResult<T = &'static str> = Result<T, ServiceError>; + +pub type JsonResult<T> = Result<T, ServiceError>; + +impl IntoResponse for ServiceError { + fn into_response(self) -> Response { + let body = body::boxed(body::Full::from(self.to_string())); + + Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(body) + .unwrap() + } +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..ba319d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,63 @@ -fn main() { - println!("Hello, world!"); +use axum::{ + error_handling::HandleErrorLayer, + http::StatusCode, + response::IntoResponse, + routing::get, + Json, Router +}; + +use serde::{Deserialize, Serialize}; +use std::{net::SocketAddr, time::Duration, str::FromStr}; + +use tower::{BoxError, ServiceBuilder}; +use tower_http::trace::TraceLayer; + +use tracing_subscriber::prelude::*; + +mod errors; + +mod handlers; + +#[tokio::main] +async fn main() { + kankyo::init(); + color_eyre::install().unwrap(); + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::new( + std::env::var("RUST_LOG") + .unwrap_or_else(|_| "waifud=info,tower_http=debug".into()), + )) + .with(tracing_subscriber::fmt::layer()) + .init(); + + let app = Router::new() + .route("/health", get(health_check)) + .route("/waifus/list", get(handlers::waifus::list)) + .layer( ServiceBuilder::new() + .layer(HandleErrorLayer::new(|error: BoxError| async move { + if error.is::<tower::timeout::error::Elapsed>() { + Ok(StatusCode::REQUEST_TIMEOUT) + } else { + Err(( + StatusCode::INTERNAL_SERVER_ERROR, + format!("Unhandled internal error: {}", error), + )) + } + })) + .timeout(Duration::from_secs(10)) + .layer(TraceLayer::new_for_http()) + .into_inner(), + ); + + let addr = SocketAddr::from_str(std::env::var("BIND_ADDR").unwrap().as_str().into()).unwrap(); + tracing::info!("Listening on {}", addr); + + axum::Server::bind(&addr) + .serve(app.into_make_service()) + .await + .unwrap(); +} + +async fn health_check() -> &'static str { + "OK" } |