错误处理

概述

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))
}

最佳实践

  1. 使用类型系统:利用Rust的类型系统进行错误处理

  2. 错误传播:合理使用?运算符传播错误

  3. 错误转换:实现必要的错误类型转换

  4. 日志记录:记录足够的错误上下文信息

  5. 优雅降级:实现合适的错误恢复机制

示例:完整的错误处理流程

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?