daoyi_cloud_common/
error.rs1use salvo::http::{ParseError, StatusCode, StatusError};
2use salvo::oapi::{self, EndpointOutRegister, ToSchema};
3use salvo::prelude::*;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub enum AppError {
8 #[error("public: `{0}`")]
9 Public(String),
10 #[error("internal: `{0}`")]
11 Internal(String),
12 #[error("salvo internal error: `{0}`")]
13 Salvo(#[from] ::salvo::Error),
14 #[error("http status error: `{0}`")]
15 HttpStatus(#[from] StatusError),
16 #[error("http parse error:`{0}`")]
17 HttpParse(#[from] ParseError),
18 #[error("anyhow error:`{0}`")]
19 Anyhow(#[from] anyhow::Error),
20 #[error("rbatis::Error:`{0}`")]
21 Rbatis(#[from] rbatis::Error),
22 #[error("validation error:`{0}`")]
23 Validation(#[from] validator::ValidationErrors),
24}
25impl AppError {
26 pub fn public<S: Into<String>>(msg: S) -> Self {
27 Self::Public(msg.into())
28 }
29
30 pub fn internal<S: Into<String>>(msg: S) -> Self {
31 Self::Internal(msg.into())
32 }
33}
34
35#[async_trait]
36impl Writer for AppError {
37 async fn write(mut self, _req: &mut Request, _depot: &mut Depot, res: &mut Response) {
38 let code = match &self {
39 Self::HttpStatus(e) => e.code,
40 _ => StatusCode::INTERNAL_SERVER_ERROR,
41 };
42 res.status_code(code);
43 let data = match self {
44 Self::Salvo(e) => {
45 tracing::error!(error = ?e, "salvo error");
46 StatusError::internal_server_error().brief("Unknown error happened in salvo.")
47 }
48 Self::Public(msg) => StatusError::internal_server_error().brief(msg),
49 Self::Internal(msg) => {
50 tracing::error!(msg = msg, "internal error");
51 StatusError::internal_server_error()
52 }
53 Self::HttpStatus(e) => e,
54 e => StatusError::internal_server_error()
55 .brief(format!("Unknown error happened: {e}"))
56 .cause(e),
57 };
58 res.render(data);
59 }
60}
61impl EndpointOutRegister for AppError {
62 fn register(components: &mut salvo::oapi::Components, operation: &mut salvo::oapi::Operation) {
63 operation.responses.insert(
64 StatusCode::INTERNAL_SERVER_ERROR.as_str(),
65 oapi::Response::new("Internal server error")
66 .add_content("application/json", StatusError::to_schema(components)),
67 );
68 operation.responses.insert(
69 StatusCode::NOT_FOUND.as_str(),
70 oapi::Response::new("Not found")
71 .add_content("application/json", StatusError::to_schema(components)),
72 );
73 operation.responses.insert(
74 StatusCode::BAD_REQUEST.as_str(),
75 oapi::Response::new("Bad request")
76 .add_content("application/json", StatusError::to_schema(components)),
77 );
78 }
79}