Skip to content

Commit

Permalink
temp: error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
zk-steve committed Mar 10, 2024
1 parent cb4f112 commit ffe7985
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 135 deletions.
3 changes: 3 additions & 0 deletions src/adapter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ features = ["postgres"]
[dependencies.tokio]
version = "1.36.0"
features = ["full"]

[dependencies.anyhow]
version = "1.0.80"
23 changes: 13 additions & 10 deletions src/adapter/src/repositories/in_memory/question.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use std::sync::Arc;
use async_trait::async_trait;
use tokio::sync::RwLock;

use rust_core::common::errors::Error;
use rust_core::common::errors::Error::NotFound;
use rust_core::common::errors::CoreError;
use rust_core::entities::question::{QuestionEntity, QuestionId};
use rust_core::entities::question_filter::QuestionFilter;
use rust_core::ports::question::QuestionPort;
Expand All @@ -31,15 +30,15 @@ impl QuestionInMemoryRepository {

#[async_trait]
impl QuestionPort for QuestionInMemoryRepository {
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, Error> {
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError> {
self.questions
.write()
.await
.insert(question.id.clone(), question.clone());
Ok(question.clone())
}

async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, Error> {
async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError> {
self.get(&question.id).await?;
self.questions
.write()
Expand All @@ -48,22 +47,26 @@ impl QuestionPort for QuestionInMemoryRepository {
Ok(question.clone())
}

async fn delete(&self, question_id: &QuestionId) -> Result<(), Error> {
async fn delete(&self, question_id: &QuestionId) -> Result<(), CoreError> {
self.get(question_id).await?;
self.questions.write().await.remove(question_id);
Ok(())
}

async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, Error> {
self.questions
async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, CoreError> {
Ok(self
.questions
.read()
.await
.get(question_id)
.ok_or(NotFound)
.cloned()
.ok_or(CoreError::NotFound)?
.clone())
}

async fn list(&self, question_filter: &QuestionFilter) -> Result<Vec<QuestionEntity>, Error> {
async fn list(
&self,
question_filter: &QuestionFilter,
) -> Result<Vec<QuestionEntity>, CoreError> {
Ok(self
.questions
.read()
Expand Down
20 changes: 10 additions & 10 deletions src/adapter/src/repositories/postgres/models/question.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::time::SystemTime;

use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use serde::Serialize;

use rust_core::common::errors::CoreError;
use rust_core::entities::question::QuestionEntity;
use serde::Serialize;

#[derive(Debug, Queryable, Serialize, Selectable, Insertable, AsChangeset, Identifiable)]
#[diesel(table_name = super::super::schema::questions)]
Expand All @@ -21,22 +21,22 @@ pub struct QuestionModel {
}

impl QuestionModel {
pub fn from(entity: QuestionEntity) -> Self {
QuestionModel {
id: entity.id.to_string().parse().unwrap(),
pub fn from(entity: QuestionEntity) -> Result<Self, CoreError> {
Ok(QuestionModel {
id: entity.id.to_string().parse()?,
title: entity.title,
content: entity.content,
tags: entity.tags.map(|v| v.into_iter().map(Some).collect()),
created_on: SystemTime::now(),
}
})
}

pub fn to_entity(self) -> QuestionEntity {
QuestionEntity {
id: self.id.to_string().parse().unwrap(),
pub fn to_entity(self) -> Result<QuestionEntity, CoreError> {
Ok(QuestionEntity {
id: self.id.to_string().parse()?,
title: self.title,
content: self.content,
tags: self.tags.map(|v| v.into_iter().flatten().collect()),
}
})
}
}
54 changes: 29 additions & 25 deletions src/adapter/src/repositories/postgres/question_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use diesel::{delete, insert_into, QueryDsl, RunQueryDsl, SelectableHelper};
use diesel::{update, ExpressionMethods};
use diesel_migrations::{embed_migrations, EmbeddedMigrations};

use rust_core::common::errors::Error;
use rust_core::common::errors::CoreError;
use rust_core::entities::question::{QuestionEntity, QuestionId};
use rust_core::entities::question_filter::QuestionFilter;
use rust_core::ports::question::QuestionPort;
Expand All @@ -30,49 +30,50 @@ impl QuestionDBRepository {

#[async_trait]
impl QuestionPort for QuestionDBRepository {
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, Error> {
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError> {
self.db
.get()
.await
.unwrap()
.interact(move |conn| {
let question = QuestionModel::from(question);
let question = QuestionModel::from(question).unwrap();
let response = insert_into(questions)
.values(&question)
.get_result::<QuestionModel>(conn)
.map_err(|err| match err {
diesel::result::Error::NotFound => Error::NotFound,
_ => Error::InternalError,
});
Ok(response.unwrap().to_entity())
diesel::result::Error::NotFound => CoreError::NotFound,
_ => CoreError::InternalError,
})
.unwrap();
Ok(response.to_entity().unwrap())
})
.await
.unwrap()
}

async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, Error> {
async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError> {
self.db
.get()
.await
.unwrap()
.interact(move |conn| {
let question = QuestionModel::from(question);
let question = QuestionModel::from(question)?;
let response = update(questions.filter(id.eq(question.id)))
.set(&question)
.get_result::<QuestionModel>(conn)
.map_err(|err| match err {
diesel::result::Error::NotFound => Error::NotFound,
_ => Error::InternalError,
diesel::result::Error::NotFound => CoreError::NotFound,
_ => CoreError::InternalError,
})?;

Ok(response.to_entity())
Ok(response.to_entity()?)

Check warning

Code scanning / clippy

question mark operator is useless here Warning

question mark operator is useless here
})
.await
.unwrap()
}

async fn delete(&self, question_id: &QuestionId) -> Result<(), Error> {
let question_id: i32 = question_id.to_string().parse().unwrap();
async fn delete(&self, question_id: &QuestionId) -> Result<(), CoreError> {
let question_id: i32 = question_id.to_string().parse()?;
self.db
.get()
.await
Expand All @@ -81,8 +82,8 @@ impl QuestionPort for QuestionDBRepository {
let _ = delete(questions.filter(id.eq(question_id)))
.execute(conn)
.map_err(|err| match err {
diesel::result::Error::NotFound => Error::NotFound,
_ => Error::InternalError,
diesel::result::Error::NotFound => CoreError::NotFound,
_ => CoreError::InternalError,
})?;

Ok(())
Expand All @@ -91,8 +92,8 @@ impl QuestionPort for QuestionDBRepository {
.unwrap()
}

async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, Error> {
let question_id: i32 = question_id.to_string().parse().unwrap();
async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, CoreError> {
let question_id: i32 = question_id.to_string().parse()?;
self.db
.get()
.await
Expand All @@ -103,17 +104,20 @@ impl QuestionPort for QuestionDBRepository {
.find(question_id)
.first(conn)
.map_err(|err| match err {
diesel::result::Error::NotFound => Error::NotFound,
_ => Error::InternalError,
diesel::result::Error::NotFound => CoreError::NotFound,
_ => CoreError::InternalError,
})?;

Ok(response.to_entity())
Ok(response.to_entity()?)

Check warning

Code scanning / clippy

question mark operator is useless here Warning

question mark operator is useless here
})
.await
.unwrap()
}

async fn list(&self, _question_filter: &QuestionFilter) -> Result<Vec<QuestionEntity>, Error> {
async fn list(
&self,
_question_filter: &QuestionFilter,
) -> Result<Vec<QuestionEntity>, CoreError> {
self.db
.get()
.await
Expand All @@ -123,13 +127,13 @@ impl QuestionPort for QuestionDBRepository {
.select(QuestionModel::as_select())
.load(conn)
.map_err(|err| match err {
diesel::result::Error::NotFound => Error::NotFound,
_ => Error::InternalError,
diesel::result::Error::NotFound => CoreError::NotFound,
_ => CoreError::InternalError,
})?;

Ok(question_list
.into_iter()
.map(|l| l.to_entity())
.map(|l| l.to_entity().unwrap())
.collect::<Vec<_>>())
})
.await
Expand Down
6 changes: 6 additions & 0 deletions src/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ version = "0.1.77"
[dependencies.serde]
version = "1.0"
features = ["derive"]

[dependencies.thiserror]
version = "1.0.57"

[dependencies]
anyhow = "1.0.80"
18 changes: 15 additions & 3 deletions src/core/src/common/errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
#[derive(Debug, PartialEq)]
pub enum Error {
ParseError(std::num::ParseIntError),
use thiserror::Error;

#[derive(Error, Debug)]
pub enum CoreError {
#[error("parse error {0}")]
ParseError(#[from] std::num::ParseIntError),

#[error("io error {0}")]
IOError(#[from] std::io::Error),

#[error("missing parameters")]
MissingParameters,
#[error("not found")]
NotFound,
#[error("transparent")]
InternalError,
#[error("unknown data store error")]
Unknown,
}
13 changes: 5 additions & 8 deletions src/core/src/entities/pagination_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use crate::common::errors::Error;
use crate::common::errors::CoreError;

/// Represents pagination parameters.
#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -45,17 +45,15 @@ impl PaginationEntity {
/// }
/// }
/// ```
pub fn from_query(query: &HashMap<String, String>) -> Result<Self, Error> {
pub fn from_query(query: &HashMap<String, String>) -> Result<Self, CoreError> {
let start = query
.get("start")
.unwrap_or(&"0".to_string())
.parse::<usize>()
.map_err(Error::ParseError)?;
.parse::<usize>()?;
let end = query
.get("end")
.unwrap_or(&"10".to_string())
.parse::<usize>()
.map_err(Error::ParseError)?;
.parse::<usize>()?;
Ok(PaginationEntity {
start,
end,
Expand Down Expand Up @@ -93,13 +91,12 @@ mod tests {
let mut query_params_2 = HashMap::new();
query_params_2.insert("start".to_string(), "abs".to_string());
query_params_2.insert("end".to_string(), "10".to_string());

match PaginationEntity::from_query(&query_params_2) {
Ok(_) => {
panic!("Expected an error, but got Ok");
}
Err(err) => match err {
Error::ParseError(_) => {}
CoreError::ParseError(_) => {}
_ => {
panic!("Expected ParseError error, but got {:?}", err);
}
Expand Down
6 changes: 3 additions & 3 deletions src/core/src/entities/question_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use crate::common::errors::Error;
use crate::common::errors::CoreError;
use crate::entities::filter_entity::FilterEntity;
use crate::entities::pagination_entity::PaginationEntity;

Expand Down Expand Up @@ -43,7 +43,7 @@ impl QuestionFilter {
/// }
/// }
/// ```
pub fn from_query(query: &HashMap<String, String>) -> Result<Self, Error> {
pub fn from_query(query: &HashMap<String, String>) -> Result<Self, CoreError> {
Ok(QuestionFilter {
pagination: PaginationEntity::from_query(query)?,
})
Expand Down Expand Up @@ -86,7 +86,7 @@ mod tests {
panic!("Expected an error, but got Ok");
}
Err(err) => match err {
Error::ParseError(_) => {}
CoreError::ParseError(_) => {}
_ => {
panic!("Expected MissingParameters error, but got {:?}", err);
}
Expand Down
19 changes: 11 additions & 8 deletions src/core/src/ports/question.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use async_trait::async_trait;

use crate::common::errors::Error;
use crate::common::errors::CoreError;
use crate::entities::question::{QuestionEntity, QuestionId};
use crate::entities::question_filter::QuestionFilter;

use async_trait::async_trait;

#[async_trait]
pub trait QuestionPort {
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, Error>;
async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, Error>;
async fn delete(&self, question_id: &QuestionId) -> Result<(), Error>;
async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, Error>;
async fn list(&self, question_filter: &QuestionFilter) -> Result<Vec<QuestionEntity>, Error>;
async fn add(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError>;
async fn update(&self, question: QuestionEntity) -> Result<QuestionEntity, CoreError>;
async fn delete(&self, question_id: &QuestionId) -> Result<(), CoreError>;
async fn get(&self, question_id: &QuestionId) -> Result<QuestionEntity, CoreError>;
async fn list(
&self,
question_filter: &QuestionFilter,
) -> Result<Vec<QuestionEntity>, CoreError>;
}
6 changes: 6 additions & 0 deletions src/public/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,9 @@ features = ["postgres"]
[dependencies.tokio]
version = "1.36.0"
features = ["full"]

[dependencies.thiserror]
version = "1.0.57"

[dependencies.anyhow]
version = "1.0.80"
Loading

0 comments on commit ffe7985

Please sign in to comment.