mirror of
https://github.com/DefectingCat/candy
synced 2025-07-15 16:51:34 +00:00
refactor: update router error handling
- Add not found error - Update error output, use plain text instead of json
This commit is contained in:
@ -1,27 +1,31 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde_json::json;
|
||||
use serde_repr::*;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum RouteError {
|
||||
// Common errors
|
||||
#[error("{0}")]
|
||||
Any(#[from] anyhow::Error),
|
||||
#[error("{0}")]
|
||||
Infallible(#[from] std::convert::Infallible),
|
||||
|
||||
// Route errors
|
||||
#[error("route not found")]
|
||||
RouteNotFound(),
|
||||
}
|
||||
|
||||
#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
|
||||
#[repr(u16)]
|
||||
pub enum ErrorCode {
|
||||
Normal = 200,
|
||||
InternalError = 1000,
|
||||
InternalError = 500,
|
||||
NotFound = 404,
|
||||
}
|
||||
|
||||
impl Display for ErrorCode {
|
||||
@ -30,7 +34,8 @@ impl Display for ErrorCode {
|
||||
|
||||
let res = match self {
|
||||
Normal => "",
|
||||
InternalError => "服务器内部错误",
|
||||
InternalError => "Internal Server Error",
|
||||
NotFound => "Resource Not Found",
|
||||
};
|
||||
f.write_str(res)?;
|
||||
Ok(())
|
||||
@ -38,15 +43,11 @@ impl Display for ErrorCode {
|
||||
}
|
||||
|
||||
/// Log and return INTERNAL_SERVER_ERROR
|
||||
fn log_internal_error<T: Display>(err: T) -> (StatusCode, ErrorCode, String) {
|
||||
fn log_internal_error<T: Display>(err: T) -> (StatusCode, String) {
|
||||
use ErrorCode::*;
|
||||
|
||||
error!("{err}");
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
InternalError,
|
||||
"internal server error".to_string(),
|
||||
)
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, InternalError.to_string())
|
||||
}
|
||||
|
||||
// Tell axum how to convert `AppError` into a response.
|
||||
@ -54,15 +55,17 @@ impl IntoResponse for RouteError {
|
||||
fn into_response(self) -> Response {
|
||||
use RouteError::*;
|
||||
|
||||
let (status_code, code, err_message) = match self {
|
||||
let (status_code, err_message) = match self {
|
||||
Any(err) => log_internal_error(err),
|
||||
// route errors
|
||||
RouteNotFound() => (StatusCode::NOT_FOUND, ErrorCode::NotFound.to_string()),
|
||||
};
|
||||
let body = Json(json!({
|
||||
"code": code,
|
||||
"message": code.to_string(),
|
||||
"error": err_message
|
||||
}));
|
||||
(status_code, body).into_response()
|
||||
// let body = Json(json!({
|
||||
// "code": code,
|
||||
// "message": code.to_string(),
|
||||
// "error": err_message
|
||||
// }));
|
||||
(status_code, err_message).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use axum::{extract::Path, response::IntoResponse};
|
||||
use http::Uri;
|
||||
use tracing::debug;
|
||||
@ -25,10 +27,18 @@ pub async fn serve(uri: Uri, Path(path): Path<String>) -> RouteResult<impl IntoR
|
||||
// which is `host_route.location`
|
||||
debug!("request: {:?} uri {}", path, parent_path);
|
||||
let route_map = ROUTE_MAP.read().await;
|
||||
// [TODO] custom error and not found page
|
||||
let Some(host_route) = route_map.get(parent_path) else {
|
||||
return Err(RouteError::Any(anyhow::anyhow!("route not found")));
|
||||
return Err(RouteError::RouteNotFound());
|
||||
};
|
||||
debug!("route: {:?}", host_route);
|
||||
let path = PathBuf::from(path);
|
||||
let Some(index_name) = path.file_name() else {
|
||||
return Err(RouteError::RouteNotFound());
|
||||
};
|
||||
// after route found
|
||||
debug!("request index file {:?}", index_name);
|
||||
// try find index file first
|
||||
// let host_route = app
|
||||
// .host_route
|
||||
// .get(&request.uri().path().to_string())
|
||||
|
Reference in New Issue
Block a user