错误处理
概述
Silent框架提供了完善的错误处理机制,本章节将介绍如何有效地处理和管理应用程序中的错误。
错误类型
框架内置错误
Silent框架定义了常见的错误类型:
use silent::prelude::*;
// 使用内置错误类型
let error = SilentError::BadRequest("Invalid input".to_string());
let error = SilentError::NotFound("Resource not found".to_string());
let error = SilentError::InternalServerError("Database error".to_string());自定义错误
您可以实现自己的错误类型:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct CustomError {
message: String,
}
impl Error for CustomError {}
impl fmt::Display for CustomError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}错误处理中间件
全局错误处理
使用内置的异常处理中间件:
use silent::prelude::*;
Route::new("")
.hook(ExceptionHandler::new())
.get(|_req| async {
Err(SilentError::BadRequest("Something went wrong".to_string()))
});自定义错误处理
实现自定义错误处理中间件:
use silent::prelude::*;
struct CustomErrorHandler;
#[async_trait]
impl Handler for CustomErrorHandler {
async fn handle(&self, req: Request, next: Next<'_>) -> Result {
match next.run(req).await {
Ok(response) => Ok(response),
Err(error) => {
// 自定义错误处理逻辑
let error_response = Json({
"error": error.to_string(),
"status": "error"
});
Ok(Response::new().status(500).body(error_response))
}
}
}
}错误日志记录
使用tracing记录错误
use tracing::{error, info};
Route::new("/api")
.post(|req: Request| async move {
match process_request(req).await {
Ok(result) => {
info!("Request processed successfully");
Ok(result)
}
Err(e) => {
error!("Error processing request: {}", e);
Err(e.into())
}
}
});错误响应格式化
JSON错误响应
统一的JSON错误响应格式:
use serde::Serialize;
#[derive(Serialize)]
struct ErrorResponse {
code: u16,
message: String,
details: Option<String>,
}
async fn handle_error(error: SilentError) -> Response {
let error_response = ErrorResponse {
code: error.status_code(),
message: error.to_string(),
details: Some("Additional error details".to_string()),
};
Response::new()
.status(error.status_code())
.body(Json(error_response))
}最佳实践
使用类型系统:利用Rust的类型系统进行错误处理
错误传播:合理使用
?运算符传播错误错误转换:实现必要的错误类型转换
日志记录:记录足够的错误上下文信息
优雅降级:实现合适的错误恢复机制
示例:完整的错误处理流程
use silent::prelude::*;
use tracing::{error, info};
#[derive(Debug)]
struct AppError(String);
impl From<AppError> for SilentError {
fn from(error: AppError) -> Self {
SilentError::InternalServerError(error.0)
}
}
async fn process_data(data: String) -> std::result::Result<String, AppError> {
// 处理逻辑
Ok(data)
}
Route::new("/api")
.hook(ExceptionHandler::new())
.post(|req: Request| async move {
let data = req.text().await?
match process_data(data).await {
Ok(result) => {
info!("Data processed successfully");
Ok(Json(result))
}
Err(e) => {
error!("Error processing data: {:?}", e);
Err(e.into())
}
}
});通过遵循这些错误处理最佳实践,您可以构建更加健壮和可维护的应用程序。错误处理不仅关系到应用程序的稳定性,还影响到用户体验和系统可维护性。
Last updated
Was this helpful?