#error #error-derive #json-error #rest #error-message #macro-derive #actix

resterror-derive

这是一个简单的库,用于处理REST错误,并提供了一个衍生活成宏来生成错误类型。它还提供了一个与actix-web兼容的层。

3个版本

0.1.3 2023年1月18日
0.1.2 2023年1月18日
0.1.1 2023年1月18日

#12 in #error-derive

MIT 许可证

21KB
330

Resterror

这是一个简单的库,用于以REST方式处理错误。它使用轻量级语法来定义错误及其代码。

支持

此crate使用'PO'翻译方法,并允许你在JSON文件中定义错误消息。这意味着如果你使用PO方法,错误消息将在每个语言的PO文件中定义。

因为此crate用于INSAgenda项目,所以响应的JSON格式使用以下字段定义

{
  "kind": "invalid_request",
  "messages_fr": "Requête invalide",
  "messages_en": "Invalid request",
  "origin": ""
}

将来,此crate将更加通用,并将采用以下格式

{
  "kind": "invalid_request",
  "messages": {
    "fr": "Requête invalide",
    "en": "Invalid request"
  }
}

用法

例如,你可以为actix定义一个错误

定义错误

    #[derive(resterror::AsApiError, Debug, Clone)]
    #[po_directory = "locales/"]
    pub enum Error {
        /// Invalid request
        #[error(status = "BadRequest")]
        InvalidRequest,
        /// Database timeout 
        #[error(status = "InternalServerError")]
        DatabaseTimeout,
        /// Too large request
        #[error(status = "BadRequest")]
        RequestTooLarge,
        /// SQLite error
        #[error(status = "InternalServerError", msg_id = "database")]
        SqliteError,
        /// Invalid JSON
        #[error(status = "BadRequest")]
        InvalidJson,
        /// Blocking error
        #[error(status = "InternalServerError")]
        BlockingError,
        /// Auth required
        #[error(code = 511)]
        AuthentificationRequired,
        /// Custom error
        #[error(code = 500)]
        CustomError(Translation),
    }

    impl From<BlockingError> for Error {
        fn from(_: BlockingError) -> Self { BlockingError }
    }

    impl Display for Error {
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self) }
    }

    impl actix_web::ResponseError for Error {
        fn status_code(&self) -> StatusCode {
            let api_error = self.as_api_error();
            StatusCode::from_u16(api_error.code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
        }

        fn error_response(&self) -> actix_web::HttpResponse {
            let api_error = self.as_api_error();
            actix_web::HttpResponse::build(self.status_code()).json(api_error)
        }
    }

你需要定义存放PO文件的PO目录。
每个文件的名称必须是语言代码。

使用错误

例如,你可以在actix路由中使用错误,如下所示

    #[get("/")]
    async fn index() -> Result<HttpResponse, Error> {
        Err(Error::InvalidRequest)
    }

    #[get("/custom-error")]
    async fn custom_error() -> Result<HttpResponse, Error> {
        Err(Error::CustomError(tr! {
            "fr" => "Erreur personnalisée",
            "en" => "Custom error"
        }))
    }

此错误将被转换为以下JSON

{
  "kind": "invalid_request",
  "messages_fr": "Requête invalide",
  "messages_en": "Invalid request",
  "origin": ""
}

使用以下PO文件

fr.po


msgid "invalid_request"
msgstr "Requête invalide"

en.po


msgid "invalid_request"
msgstr "Invalid request"

就是这样,你现在可以使用这个库在你的项目中以REST方式处理错误。请注意,这只是一个基本示例,你可以根据需要自定义和扩展它。

依赖

~2–14MB
~175K SLoC