aboutsummaryrefslogtreecommitdiff
path: root/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/error.rs')
-rw-r--r--src/error.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..2d0f911
--- /dev/null
+++ b/src/error.rs
@@ -0,0 +1,89 @@
1use axum::extract::rejection::JsonRejection;
2use axum::response::{IntoResponse, Response};
3use axum_extra::typed_header::TypedHeaderRejection;
4
5use crate::response::{ErrorResponse, FailResponse, SuccessResponse};
6
7pub type ApiResult<T> = Result<SuccessResponse<T>, ApiError>;
8
9pub enum ApiError {
10 // 400
11 BadJsonBody(String),
12 BadAuthTokenHeader(String),
13 UserAlreadyExists { username: String },
14 InvalidPassword,
15 NotAuthorized,
16 // 500
17 Database(String),
18 PasswordHash(String),
19 InternalJwt(String),
20}
21
22impl From<JsonRejection> for ApiError {
23 fn from(value: JsonRejection) -> Self {
24 Self::BadJsonBody(value.body_text())
25 }
26}
27
28impl From<TypedHeaderRejection> for ApiError {
29 fn from(value: TypedHeaderRejection) -> Self {
30 Self::BadAuthTokenHeader(value.to_string())
31 }
32}
33
34impl From<sea_orm::DbErr> for ApiError {
35 fn from(value: sea_orm::DbErr) -> Self {
36 Self::Database(value.to_string())
37 }
38}
39
40impl From<argon2::password_hash::Error> for ApiError {
41 fn from(value: argon2::password_hash::Error) -> Self {
42 Self::PasswordHash(value.to_string())
43 }
44}
45
46impl ToString for ApiError {
47 fn to_string(&self) -> String {
48 match self {
49 // 400
50 ApiError::BadJsonBody(..) => "BadJsonBody",
51 ApiError::BadAuthTokenHeader(..) => "BadAuthTokenHeader",
52 ApiError::UserAlreadyExists { .. } => "UserAlreadyExists",
53 ApiError::InvalidPassword => "InvalidPassword",
54 ApiError::NotAuthorized => "NotAuthorized",
55 // 500
56 ApiError::Database(..) => "Database",
57 ApiError::PasswordHash(..) => "PasswordHash",
58 ApiError::InternalJwt(..) => "InternalJwt",
59 }
60 .to_string()
61 }
62}
63
64impl IntoResponse for ApiError {
65 fn into_response(self) -> Response {
66 let kind = self.to_string();
67 match self {
68 // 400
69 ApiError::BadJsonBody(msg) => FailResponse(kind, msg).into_response(),
70 ApiError::BadAuthTokenHeader(msg) => FailResponse(kind, msg).into_response(),
71 ApiError::UserAlreadyExists { username } => FailResponse(
72 kind,
73 format!("user with username `{}` already exists", username),
74 )
75 .into_response(),
76 ApiError::InvalidPassword => {
77 FailResponse(kind, "password is invalid".to_string()).into_response()
78 }
79 ApiError::NotAuthorized => {
80 FailResponse(kind, "user is not authorized".to_string()).into_response()
81 }
82
83 // 500
84 ApiError::Database(msg) => ErrorResponse(kind, msg).into_response(),
85 ApiError::PasswordHash(msg) => ErrorResponse(kind, msg).into_response(),
86 ApiError::InternalJwt(msg) => ErrorResponse(kind, msg).into_response(),
87 }
88 }
89}