use actix_web::http::StatusCode; use actix_web::HttpResponse; use serde::ser::SerializeStruct; use serde::{Serialize, Serializer}; use sqlx::migrate::MigrateError; use sqlx::Error; #[derive(Debug)] pub enum DatabaseError { DeleteError, InsertError, InsertGetError, NotFound, Protected, EmptyDataInsert, UpdateError, UpdateGetError, MigrationError(MigrateError), Unknown(Error), } impl DatabaseError { pub fn get_code(&self) -> StatusCode { match self { DatabaseError::NotFound => StatusCode::NOT_FOUND, DatabaseError::Protected => StatusCode::FORBIDDEN, _ => StatusCode::INTERNAL_SERVER_ERROR, } } } impl Serialize for DatabaseError { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let mut s = serializer.serialize_struct("error", 3)?; s.serialize_field("type", "database-error")?; s.serialize_field("code", &self.get_code().as_u16())?; s.serialize_field("description", &String::from(self))?; s.end() } } impl From<&DatabaseError> for String { fn from(err: &DatabaseError) -> Self { String::from(match err { DatabaseError::InsertError => "error on inserting into database", DatabaseError::InsertGetError => { "error on retrieving new entry from database (your entry was saved)" } DatabaseError::NotFound => "model was not found in database", DatabaseError::DeleteError => "error on deleting from database", DatabaseError::Protected => "model is protected", DatabaseError::UpdateError => "error on updating the model", DatabaseError::UpdateGetError => { "error on retrieving updated model from database (your entry was saved)" } DatabaseError::MigrationError(_) => "error on running migrations", DatabaseError::Unknown(_) => "unknown error", DatabaseError::EmptyDataInsert => "empty data was attempted to be inserted", }) } } impl From<DatabaseError> for HttpResponse { fn from(err: DatabaseError) -> Self { HttpResponse::build(err.get_code()).json(err) } } impl From<Error> for DatabaseError { fn from(value: Error) -> Self { match value { Error::RowNotFound => DatabaseError::NotFound, _ => DatabaseError::Unknown(value), } } } impl From<MigrateError> for DatabaseError { fn from(value: MigrateError) -> Self { Self::MigrationError(value) } }