feat(backend): ayarlar, MongoDB bağlantısı, Türkçe hata yapısı ve DB'li health check
- config.rs: ortam değişkenleri ve doğrulama - db.rs: bağlantı + ping (5 sn zaman aşımı) - error.rs: AppError → Türkçe JSON hata yanıtı - /api/health: veritabanına erişilemezse 503 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
//! Uygulama genelindeki hata türü.
|
||||
//! Kullanıcıya Türkçe ve sade mesaj döner; teknik detay yalnızca loga yazılır.
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AppError {
|
||||
#[error("Kayıt bulunamadı")]
|
||||
NotFound,
|
||||
#[error("{0}")]
|
||||
BadRequest(String),
|
||||
#[error("Oturum açmanız gerekiyor")]
|
||||
Unauthorized,
|
||||
#[error("Bu işlem için yetkiniz yok")]
|
||||
Forbidden,
|
||||
#[error("{0}")]
|
||||
Conflict(String),
|
||||
#[error("Çok fazla deneme yapıldı, lütfen biraz sonra tekrar deneyin")]
|
||||
TooManyRequests,
|
||||
#[error("veritabanı hatası: {0}")]
|
||||
Database(#[from] mongodb::error::Error),
|
||||
#[error("iç hata: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
impl AppError {
|
||||
fn status_and_code(&self) -> (StatusCode, &'static str) {
|
||||
match self {
|
||||
Self::NotFound => (StatusCode::NOT_FOUND, "not_found"),
|
||||
Self::BadRequest(_) => (StatusCode::BAD_REQUEST, "bad_request"),
|
||||
Self::Unauthorized => (StatusCode::UNAUTHORIZED, "unauthorized"),
|
||||
Self::Forbidden => (StatusCode::FORBIDDEN, "forbidden"),
|
||||
Self::Conflict(_) => (StatusCode::CONFLICT, "conflict"),
|
||||
Self::TooManyRequests => (StatusCode::TOO_MANY_REQUESTS, "too_many_requests"),
|
||||
Self::Database(_) | Self::Internal(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "internal")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
let (status, code) = self.status_and_code();
|
||||
|
||||
let message = if status.is_server_error() {
|
||||
// Teknik detay sadece logda; kullanıcıya genel mesaj.
|
||||
tracing::error!(error = %self, "sunucu hatası");
|
||||
"Beklenmeyen bir hata oluştu, lütfen tekrar deneyin".to_string()
|
||||
} else {
|
||||
self.to_string()
|
||||
};
|
||||
|
||||
(
|
||||
status,
|
||||
Json(json!({ "error": { "code": code, "message": message } })),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
/// Route fonksiyonlarında kısa dönüş tipi: `AppResult<Json<T>>`
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
Reference in New Issue
Block a user