feat: improve error handling

return status codes, messages
This commit is contained in:
Sebastian Pravda 2022-11-01 19:20:49 +01:00
parent 56f64a43c8
commit 05369b977a
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
4 changed files with 59 additions and 34 deletions

View file

@ -28,10 +28,6 @@ pub use entity::candidate::Entity as Candidate;
use portfolio_core::crypto::random_8_char_string; use portfolio_core::crypto::random_8_char_string;
/* fn custom_err_from_service_err(service_err: ServiceError) -> Custom<String> {
Custom(Status::from_code(service_err.0.code).unwrap_or_default(), service_err.1.to_string())
} */
#[post("/", data = "<post_form>")] #[post("/", data = "<post_form>")]
async fn create(conn: Connection<'_, Db>, post_form: Json<RegisterRequest>) -> Result<String, Custom<String>> { async fn create(conn: Connection<'_, Db>, post_form: Json<RegisterRequest>) -> Result<String, Custom<String>> {
let db = conn.into_inner(); let db = conn.into_inner();
@ -39,11 +35,15 @@ async fn create(conn: Connection<'_, Db>, post_form: Json<RegisterRequest>) -> R
let plain_text_password = random_8_char_string(); let plain_text_password = random_8_char_string();
CandidateService::create(db, form.application_id, &plain_text_password, form.personal_id_number) let candidate = CandidateService::create(db, form.application_id, &plain_text_password, form.personal_id_number)
.await .await;
.unwrap();
Ok(plain_text_password) if candidate.is_err() { // TODO cleanup
let e = candidate.err().unwrap();
return Err(Custom(Status::from_code(e.code()).unwrap_or_default(), e.message()));
}
Ok(plain_text_password)
} }
#[get("/whoami")] #[get("/whoami")]
@ -65,16 +65,7 @@ async fn login(conn: Connection<'_, Db>, login_form: Json<LoginRequest>, ip_addr
) )
.await; .await;
if session_token.is_ok() { session_token.map_err(|e| Custom(Status::from_code(e.code()).unwrap_or_default(), e.message()))
return Ok(
session_token.ok().unwrap()
);
} else {
return Err(
// custom_err_from_service_err(session_token.err().unwrap())
Custom(Status::Unauthorized, "TODO".to_string())
)
}
} }
#[get("/hello")] #[get("/hello")]

View file

@ -26,8 +26,3 @@ impl Mutation {
.await .await
} }
} }
/*
#[cfg(test)]
mod tests {
#[tokio::fs]
} */

View file

@ -23,6 +23,21 @@ pub const USER_NOT_FOUND_BY_SESSION_ID: ServiceError = ServiceError(Status { cod
"User not found, please contact technical support"); // Shouldn't ever happen "User not found, please contact technical support"); // Shouldn't ever happen
pub struct ServiceError<'a>(pub Status, pub &'a str); */ pub struct ServiceError<'a>(pub Status, pub &'a str); */
/* pub struct ServiceError {
pub code: u16,
pub message: String,
}
impl ServiceError {
pub const InvalidCredentials: ServiceError = ServiceError { code: 401, message: "Invalid credentials".to_string() };
pub const ExpiredSession: ServiceError = ServiceError { code: 401, message: "Session expired, please login again".to_string() };
pub const JwtError: ServiceError = ServiceError { code: 500, message: "Error while encoding JWT".to_string() };
pub const UserNotFound: ServiceError = ServiceError { code: 404, message: "User not found".to_string() };
pub const DbError: ServiceError = ServiceError { code: 500, message: "Database error".to_string() };
pub const UserNotFoundByJwtId: ServiceError = ServiceError { code: 500, message: "User not found, please contact technical support".to_string() };
pub const UserNotFoundBySessionId: ServiceError = ServiceError { code: 500, message: "User not found, please contact technical support".to_string() };
} */
pub enum ServiceError { pub enum ServiceError {
InvalidCredentials, InvalidCredentials,
ExpiredSession, ExpiredSession,
@ -33,16 +48,40 @@ pub enum ServiceError {
UserNotFoundBySessionId, UserNotFoundBySessionId,
} }
impl std::fmt::Debug for ServiceError { impl ServiceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { pub fn code(&self) -> u16 {
match self { match self {
ServiceError::InvalidCredentials => write!(f, "Invalid credentials"), ServiceError::InvalidCredentials => 401,
ServiceError::ExpiredSession => write!(f, "Session expired, please login again"), ServiceError::ExpiredSession => 401,
ServiceError::JwtError => write!(f, "Error while encoding JWT"), ServiceError::JwtError => 500,
ServiceError::UserNotFound => write!(f, "User not found"), ServiceError::UserNotFound => 404,
ServiceError::DbError => write!(f, "Database error"), ServiceError::DbError => 500,
ServiceError::UserNotFoundByJwtId => write!(f, "User not found, please contact technical support"), ServiceError::UserNotFoundByJwtId => 500,
ServiceError::UserNotFoundBySessionId => write!(f, "User not found, please contact technical support"), ServiceError::UserNotFoundBySessionId => 500,
}
}
pub fn message(&self) -> String {
match self {
ServiceError::InvalidCredentials => "Invalid credentials".to_string(),
ServiceError::ExpiredSession => "Session expired, please login again".to_string(),
ServiceError::JwtError => "Error while encoding JWT".to_string(),
ServiceError::UserNotFound => "User not found".to_string(),
ServiceError::DbError => "Database error".to_string(),
ServiceError::UserNotFoundByJwtId => "User not found, please contact technical support".to_string(),
ServiceError::UserNotFoundBySessionId => "User not found, please contact technical support".to_string(),
} }
} }
} }
impl std::fmt::Debug for ServiceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ServiceError {{ code: {}, message: {} }}", self.code(), self.message())
}
}
impl std::fmt::Display for ServiceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ServiceError {{ code: {}, message: {} }}", self.code(), self.message())
}
}

View file

@ -84,7 +84,7 @@ mod tests {
let secret_message = "trnka".to_string(); let secret_message = "trnka".to_string();
let candidate = CandidateService::create(&db, 5555555, &plain_text_password, "".to_string()).await.unwrap(); let candidate = CandidateService::create(&db, 5555555, &plain_text_password, "".to_string()).await.ok().unwrap();
let encrypted_message = crypto::encrypt_password_with_recipients(&secret_message, vec![&candidate.public_key]).await.unwrap(); let encrypted_message = crypto::encrypt_password_with_recipients(&secret_message, vec![&candidate.public_key]).await.unwrap();