errors
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 7m23s

This commit is contained in:
Dmitri 2026-04-24 22:04:50 +02:00
parent 0f7e7994ff
commit f5fc85cb00
Signed by: kanopo
GPG Key ID: 759ADD40E3132AC7
6 changed files with 71 additions and 42 deletions

1
Cargo.lock generated
View File

@ -1081,6 +1081,7 @@ dependencies = [
"axum",
"dotenvy",
"sqlx",
"thiserror",
"tokio",
"tracing",
"tracing-appender",

View File

@ -12,3 +12,4 @@ tracing-tree = "0.4.1"
tokio = { version = "1.52.1", features = ["rt-multi-thread", "macros", "signal"] }
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres", "time", "uuid" ] }
axum = "0.8.9"
thiserror = "2"

View File

@ -2,6 +2,8 @@ use std::env;
use dotenvy::dotenv;
use crate::errors::AppError;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AppEnv {
Development,
@ -9,12 +11,15 @@ pub enum AppEnv {
}
impl AppEnv {
pub fn from_env() -> Self {
match std::env::var("APP_ENV").as_deref() {
Ok("prod") => AppEnv::Production,
Ok("dev") => AppEnv::Development,
Ok(other) => panic!("Invalid APP_ENV: {}", other),
Err(_) => panic!("APP_ENV must be set"),
pub fn from_env() -> Result<Self, AppError> {
match env::var("APP_ENV").as_deref() {
Ok("prod") => Ok(AppEnv::Production),
Ok("dev") => Ok(AppEnv::Development),
Ok(other) => Err(AppError::InvalidConfig(format!(
"Invalid APP_ENV: {}",
other
))),
Err(_) => Err(AppError::InvalidConfig("APP_ENV must be set".to_string())),
}
}
}
@ -27,12 +32,12 @@ pub struct Config {
}
impl Config {
pub fn load() -> Self {
pub fn load() -> Result<Self, AppError> {
dotenv().ok();
Self {
db_url: env::var("DB_URL").expect("DB_URL is not configured"),
socket_address: env::var("SOCKET_ADDRESS").expect("SOCKET_ADDRESS is not configured"),
app_env: AppEnv::from_env(),
}
Ok(Self {
db_url: env::var("DB_URL")?,
socket_address: env::var("SOCKET_ADDRESS")?,
app_env: AppEnv::from_env()?,
})
}
}

View File

@ -1,22 +1,19 @@
use std::process::exit;
use sqlx::{Pool, Postgres, postgres::PgPoolOptions, migrate::MigrateError};
use sqlx::{Pool, Postgres, postgres::PgPoolOptions};
use crate::errors::AppError;
pub async fn init(db_url: &str) -> Pool<Postgres> {
let db = match PgPoolOptions::new().connect(db_url).await {
Ok(p) => p,
Err(_) => {
tracing::error!("Failed to connect to the database");
exit(1);
}
};
match sqlx::migrate!().run(&db).await {
Ok(_) => tracing::info!("Migration completed succesfully"),
Err(_) => {
tracing::error!("Failed to apply migrations");
exit(1)
}
}
pub async fn init(db_url: &str) -> Result<Pool<Postgres>, AppError> {
let db = PgPoolOptions::new()
.connect(db_url)
.await
.map_err(AppError::DbConnect)?;
db
sqlx::migrate!()
.run(&db)
.await
.map_err(|e: MigrateError| AppError::InvalidConfig(format!("Migration failed: {}", e)))?;
tracing::info!("Migration completed successfully");
Ok(db)
}

26
src/errors.rs Normal file
View File

@ -0,0 +1,26 @@
use thiserror::Error;
#[derive(Debug, Error)]
pub enum AppError {
#[error("Failed to load configuration: {0}")]
Config(#[from] std::env::VarError),
#[error("Invalid configuration value: {0}")]
InvalidConfig(String),
#[error("Failed to connect to database")]
DbConnect(#[from] sqlx::Error),
#[error("Failed to bind to address")]
Bind(#[from] std::io::Error),
}
#[derive(Debug, Error)]
#[error("Application error: {0}")]
pub struct MainError(pub AppError);
impl From<AppError> for MainError {
fn from(err: AppError) -> Self {
Self(err)
}
}

View File

@ -2,27 +2,26 @@ use axum::{Router, routing::get};
mod config;
mod database;
mod errors;
mod logging;
use errors::{AppError, MainError};
#[tokio::main]
async fn main() {
let cfg = config::Config::load();
async fn main() -> Result<(), MainError> {
let cfg = config::Config::load()?;
let _logging_guard = logging::LoggerConfig::init(cfg.app_env);
let _db = database::init(&cfg.db_url).await;
let app = Router::new().route(
"/",
get(|| async {
tracing::info!("ciao");
return "ciao";
}),
);
let _db = database::init(&cfg.db_url).await?;
let app = Router::new().route("/", get(|| async { "ciao" }));
let listener = tokio::net::TcpListener::bind(&cfg.socket_address)
.await
.unwrap();
.map_err(AppError::Bind)?;
tracing::info!("Server started on {}", cfg.socket_address);
axum::serve(listener, app)
.with_graceful_shutdown(logging::shutdown_signal())
.await
.unwrap();
.map_err(AppError::Bind)?;
Ok(())
}