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;
/* 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>")]
async fn create(conn: Connection<'_, Db>, post_form: Json<RegisterRequest>) -> Result<String, Custom<String>> {
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();
CandidateService::create(db, form.application_id, &plain_text_password, form.personal_id_number)
.await
.unwrap();
let candidate = CandidateService::create(db, form.application_id, &plain_text_password, form.personal_id_number)
.await;
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)
Ok(plain_text_password)
}
#[get("/whoami")]
@ -65,16 +65,7 @@ async fn login(conn: Connection<'_, Db>, login_form: Json<LoginRequest>, ip_addr
)
.await;
if session_token.is_ok() {
return Ok(
session_token.ok().unwrap()
);
} else {
return Err(
// custom_err_from_service_err(session_token.err().unwrap())
Custom(Status::Unauthorized, "TODO".to_string())
)
}
session_token.map_err(|e| Custom(Status::from_code(e.code()).unwrap_or_default(), e.message()))
}
#[get("/hello")]

View file

@ -25,9 +25,4 @@ impl Mutation {
.insert(db)
.await
}
}
/*
#[cfg(test)]
mod tests {
#[tokio::fs]
} */
}

View file

@ -22,7 +22,22 @@ pub const USER_NOT_FOUND_BY_JWT_ID: ServiceError = ServiceError(Status { code: 5
pub const USER_NOT_FOUND_BY_SESSION_ID: ServiceError = ServiceError(Status { code: 500 }, // User got somehow deleted
"User not found, please contact technical support"); // Shouldn't ever happen
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 {
InvalidCredentials,
ExpiredSession,
@ -33,16 +48,40 @@ pub enum ServiceError {
UserNotFoundBySessionId,
}
impl std::fmt::Debug for ServiceError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl ServiceError {
pub fn code(&self) -> u16 {
match self {
ServiceError::InvalidCredentials => write!(f, "Invalid credentials"),
ServiceError::ExpiredSession => write!(f, "Session expired, please login again"),
ServiceError::JwtError => write!(f, "Error while encoding JWT"),
ServiceError::UserNotFound => write!(f, "User not found"),
ServiceError::DbError => write!(f, "Database error"),
ServiceError::UserNotFoundByJwtId => write!(f, "User not found, please contact technical support"),
ServiceError::UserNotFoundBySessionId => write!(f, "User not found, please contact technical support"),
ServiceError::InvalidCredentials => 401,
ServiceError::ExpiredSession => 401,
ServiceError::JwtError => 500,
ServiceError::UserNotFound => 404,
ServiceError::DbError => 500,
ServiceError::UserNotFoundByJwtId => 500,
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 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();