Initial commit

This commit is contained in:
2026-10-06 08:24:08 +03:00
commit eb1fd6e2ff
19 changed files with 2112 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
use axum::{Json, http::StatusCode, response::IntoResponse};
use thiserror::Error;
use crate::{sync::SyncError, users::UserError};
// The AppError represents the different error types from upstream kosync server
#[derive(Error, Debug)]
pub enum AppError {
#[error("Username already taken")]
UsernameTaken,
#[error("Unauthorized")]
Unauthorized,
#[error("Account not found")]
AccountNotFound,
#[error(transparent)]
Internal(#[from] anyhow::Error),
}
impl From<UserError> for AppError {
fn from(value: UserError) -> Self {
match value {
UserError::UnknownError(error) => Self::Internal(error),
UserError::UserAlreadyExists => Self::UsernameTaken,
UserError::DatabaseFailure(error) => Self::Internal(error.into()),
}
}
}
impl From<SyncError> for AppError {
fn from(value: SyncError) -> Self {
match value {
SyncError::DatabaseFailure(error) => Self::Internal(error.into()),
}
}
}
impl IntoResponse for AppError {
fn into_response(self) -> axum::response::Response {
let (status, error_code, msg) = match self {
AppError::UsernameTaken => (StatusCode::PAYMENT_REQUIRED, 2002, "Username is already registered"),
AppError::Internal(error) => {
tracing::error!(err=?error, "Internal server error");
(StatusCode::INTERNAL_SERVER_ERROR, 2000, "Internal server error")
},
AppError::Unauthorized => {
(StatusCode::UNAUTHORIZED, 2001, "Unauthorized")
}
AppError::AccountNotFound => {
(StatusCode::UNAUTHORIZED, 2006, "Account not found")
}
};
let body = serde_json::json!({
"code": error_code,
"message": msg
});
(status, Json(body)).into_response()
}
}