/
mcmare
/
RustAPI
Обзор
Документация
Войти
/
mcmare
/
RustAPI
Код
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
core/src/error.rs
76 строк
2 KB
mcmare
Add core HTTP layer: axum bootstrap, auth middleware, error envelope, health route
18 июл 2026, 16:11
18 июл 2026, 16:11
ee13146
Код
Авторство
О чём код?
use axum::{ http::StatusCode, response::{IntoResponse, Response}, Json, }; use serde::Serialize; /// Uniform API error, always rendered as `{ "error": { "code", "message" } }`. #[derive(Debug, thiserror::Error)] pub enum ApiError { #[error("{0}")] Validation(String), #[error("unauthorized")] Unauthorized, #[error("not found")] NotFound, #[error("conflict: {0}")] Conflict(String), #[error("internal error")] Internal(#[from] anyhow::Error), } pub type ApiResult<T> = Result<T, ApiError>; impl ApiError { fn code(&self) -> &'static str { match self { ApiError::Validation(_) => "VALIDATION_ERROR", ApiError::Unauthorized => "UNAUTHORIZED", ApiError::NotFound => "NOT_FOUND", ApiError::Conflict(_) => "CONFLICT", ApiError::Internal(_) => "INTERNAL_ERROR", } } fn status(&self) -> StatusCode { match self { ApiError::Validation(_) => StatusCode::BAD_REQUEST, ApiError::Unauthorized => StatusCode::UNAUTHORIZED, ApiError::NotFound => StatusCode::NOT_FOUND, ApiError::Conflict(_) => StatusCode::CONFLICT, ApiError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR, } } } #[derive(Serialize)] struct ErrorBody { error: ErrorDetail, } #[derive(Serialize)] struct ErrorDetail { code: &'static str, message: String, } impl IntoResponse for ApiError { fn into_response(self) -> Response { // Internal errors are logged with full detail but never leaked to the client. if let ApiError::Internal(err) = &self { tracing::error!(error = ?err, "internal error"); } let status = self.status(); let body = ErrorBody { error: ErrorDetail { code: self.code(), message: match &self { ApiError::Internal(_) => "internal server error".to_string(), other => other.to_string(), }, }, }; (status, Json(body)).into_response() } }