From 0c8ec34f27f7ad3e30036e65e394c645f3e3ae54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGiems=E2=80=9D?= <“hubert.wabia@gmail.com”> Date: Thu, 7 Mar 2024 14:42:12 +0100 Subject: [PATCH 1/3] custom db error --- database/Cargo.toml | 2 +- database/src/structs/db_error.rs | 28 ++++++++++++++++++ database/src/structs/mod.rs | 1 + database/src/tables/sessions/update.rs | 36 ++++++++++++++++++----- server/src/http/cloud/register_new_app.rs | 15 ++++++++-- 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 database/src/structs/db_error.rs diff --git a/database/Cargo.toml b/database/Cargo.toml index 0ecc7f9f..13d2a61f 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -12,4 +12,4 @@ ts-rs = { workspace = true } tokio = { workspace = true } dotenvy = { workspace = true } anyhow = { workspace = true } -axum = { workspace = true } \ No newline at end of file +log = { workspace = true } \ No newline at end of file diff --git a/database/src/structs/db_error.rs b/database/src/structs/db_error.rs new file mode 100644 index 00000000..adbcdbbd --- /dev/null +++ b/database/src/structs/db_error.rs @@ -0,0 +1,28 @@ +use std::fmt; + +#[derive(Debug)] +pub enum DbError { + DatabaseError(String), + SqlxDbError(sqlx::Error), +} + +impl fmt::Display for DbError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + DbError::DatabaseError(ref err) => write!(f, "Database error: {}", err), + DbError::SqlxDbError(ref err) => write!(f, "Sqlx database error: {}", err), + } + } +} + +impl From for DbError { + fn from(error: sqlx::Error) -> DbError { + DbError::SqlxDbError(error) + } +} + +impl From for DbError { + fn from(error: String) -> DbError { + DbError::DatabaseError(error) + } +} diff --git a/database/src/structs/mod.rs b/database/src/structs/mod.rs index 5c2cc57d..861ad48c 100644 --- a/database/src/structs/mod.rs +++ b/database/src/structs/mod.rs @@ -1,5 +1,6 @@ pub mod client_data; pub mod consts; +pub mod db_error; pub mod entity_type; pub mod filter_requests; pub mod privilege_level; diff --git a/database/src/tables/sessions/update.rs b/database/src/tables/sessions/update.rs index d20c2a61..cc70ce88 100644 --- a/database/src/tables/sessions/update.rs +++ b/database/src/tables/sessions/update.rs @@ -1,5 +1,6 @@ use super::table_struct::{DbNcSession, SESSIONS_KEYS, SESSIONS_TABLE_NAME}; use crate::{db::Db, structs::client_data::ClientData}; +use log::error; use sqlx::{ query, types::chrono::{DateTime, Utc}, @@ -16,7 +17,10 @@ impl Db { // 1. Save the new session if let Err(err) = self.save_new_session(&mut tx, &session).await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } @@ -31,7 +35,10 @@ impl Db { ) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } @@ -120,7 +127,10 @@ impl Db { { Ok(profile_id) => profile_id, Err(err) => { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } }; @@ -142,7 +152,10 @@ impl Db { .await; if let Err(err) = query_result { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } @@ -160,7 +173,10 @@ impl Db { ) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } } else { @@ -182,7 +198,10 @@ impl Db { ) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } } @@ -199,7 +218,10 @@ impl Db { ) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); return Err(err); } diff --git a/server/src/http/cloud/register_new_app.rs b/server/src/http/cloud/register_new_app.rs index 8d2b86a5..2829ecae 100644 --- a/server/src/http/cloud/register_new_app.rs +++ b/server/src/http/cloud/register_new_app.rs @@ -117,7 +117,10 @@ pub async fn register_new_app( .register_new_app_within_tx(&mut tx, &db_registered_app) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); error!("Failed to create app: {:?}", err); return Err(( StatusCode::INTERNAL_SERVER_ERROR, @@ -138,7 +141,10 @@ pub async fn register_new_app( .add_new_privilege_within_tx(&mut tx, &user_app_privilege) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); error!("Failed to create user app privilege {:?}", err); return Err(( StatusCode::INTERNAL_SERVER_ERROR, @@ -156,7 +162,10 @@ pub async fn register_new_app( ) .await { - tx.rollback().await.unwrap(); + let _ = tx + .rollback() + .await + .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); error!("Failed to add read privileges to existing users: {:?}", err); return Err(( StatusCode::INTERNAL_SERVER_ERROR, From 78024375f5d06de5eb3dfcc1dc0b51cfa1b75560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGiems=E2=80=9D?= <“hubert.wabia@gmail.com”> Date: Thu, 7 Mar 2024 15:09:09 +0100 Subject: [PATCH 2/3] db custom error --- .../connections_stats.rs | 9 ++--- .../requests_stats.rs | 9 ++--- .../sessions_stats.rs | 9 ++--- database/src/tables/client_profiles/select.rs | 6 ++- database/src/tables/client_profiles/update.rs | 13 ++++-- .../src/tables/connection_events/select.rs | 26 +++++++----- .../src/tables/connection_events/update.rs | 17 ++++---- database/src/tables/grafana_users/select.rs | 14 +++---- database/src/tables/grafana_users/update.rs | 9 +++-- database/src/tables/public_keys/select.rs | 6 ++- database/src/tables/public_keys/update.rs | 15 ++++--- database/src/tables/registered_app/select.rs | 19 ++++----- database/src/tables/registered_app/update.rs | 10 ++--- database/src/tables/requests/select.rs | 12 +++--- database/src/tables/requests/update.rs | 13 +++--- .../src/tables/session_public_keys/select.rs | 6 ++- .../src/tables/session_public_keys/update.rs | 5 ++- database/src/tables/sessions/select.rs | 19 ++++----- database/src/tables/sessions/update.rs | 24 ++++++----- database/src/tables/team/select.rs | 40 ++++++++++++------- database/src/tables/team/update.rs | 14 +++---- database/src/tables/test_utils.rs | 8 ++-- .../src/tables/user_app_privileges/select.rs | 26 +++++++----- .../src/tables/user_app_privileges/update.rs | 18 +++++---- 24 files changed, 199 insertions(+), 148 deletions(-) diff --git a/database/src/aggregated_views_queries/connections_stats.rs b/database/src/aggregated_views_queries/connections_stats.rs index d46c86f8..e5f09a77 100644 --- a/database/src/aggregated_views_queries/connections_stats.rs +++ b/database/src/aggregated_views_queries/connections_stats.rs @@ -1,9 +1,8 @@ use crate::{ db::Db, - structs::{filter_requests::ConnectionStats, time_filters::TimeFilter}, + structs::{db_error::DbError, filter_requests::ConnectionStats, time_filters::TimeFilter}, tables::utils::{format_view_keys, format_view_name}, }; -use sqlx::Error; pub const CONNECTIONS_STATS_BASE_VIEW_NAME: &str = "connection_stats_per_app_and_network"; pub const CONNECTIONS_STATS_BASE_KEYS: [(&'static str, bool); 5] = [ @@ -20,7 +19,7 @@ impl Db { app_id: &str, network: Option<&str>, filter: TimeFilter, - ) -> Result, Error> { + ) -> Result, DbError> { let start_date = filter.to_date(); let bucket_size = filter.bucket_size(); @@ -29,8 +28,7 @@ impl Db { "1 hour" => "hourly", "1 day" => "daily", "1 month" => "monthly", - // TODO for now return WorkerCrashed but later create custom error - _ => return Err(Error::WorkerCrashed), + _ => return Err(DbError::DatabaseError("Invalid bucket size".to_string())), }; let formatted_keys = format_view_keys(prefix, &CONNECTIONS_STATS_BASE_KEYS); @@ -55,6 +53,7 @@ impl Db { .bind(start_date) .fetch_all(&self.connection_pool) .await + .map_err(|e| e.into()) } } diff --git a/database/src/aggregated_views_queries/requests_stats.rs b/database/src/aggregated_views_queries/requests_stats.rs index 183c1c80..7f15b879 100644 --- a/database/src/aggregated_views_queries/requests_stats.rs +++ b/database/src/aggregated_views_queries/requests_stats.rs @@ -1,9 +1,8 @@ use crate::{ db::Db, - structs::{filter_requests::RequestsStats, time_filters::TimeFilter}, + structs::{db_error::DbError, filter_requests::RequestsStats, time_filters::TimeFilter}, tables::utils::{format_view_keys, format_view_name}, }; -use sqlx::Error; pub const REQUESTS_STATS_BASE_VIEW_NAME: &str = "requests_stats_per_app"; pub const REQUESTS_STATS_BASE_KEYS: [(&'static str, bool); 4] = [ @@ -18,7 +17,7 @@ impl Db { &self, app_id: &str, filter: TimeFilter, - ) -> Result, Error> { + ) -> Result, DbError> { let start_date = filter.to_date(); let bucket_size = filter.bucket_size(); @@ -27,8 +26,7 @@ impl Db { "1 hour" => "hourly", "1 day" => "daily", "1 month" => "monthly", - // TODO for now return WorkerCrashed but later create custom error - _ => return Err(Error::WorkerCrashed), + _ => return Err(DbError::DatabaseError("Invalid bucket size".to_string())), }; let formatted_keys = format_view_keys(prefix, &REQUESTS_STATS_BASE_KEYS); @@ -48,6 +46,7 @@ impl Db { .bind(start_date) .fetch_all(&self.connection_pool) .await + .map_err(|e| e.into()) } } diff --git a/database/src/aggregated_views_queries/sessions_stats.rs b/database/src/aggregated_views_queries/sessions_stats.rs index 5e7a665f..007db587 100644 --- a/database/src/aggregated_views_queries/sessions_stats.rs +++ b/database/src/aggregated_views_queries/sessions_stats.rs @@ -1,9 +1,8 @@ use crate::{ db::Db, - structs::{filter_requests::SessionsStats, time_filters::TimeFilter}, + structs::{db_error::DbError, filter_requests::SessionsStats, time_filters::TimeFilter}, tables::utils::{format_view_keys, format_view_name}, }; -use sqlx::Error; pub const SESSIONS_STATS_BASE_VIEW_NAME: &str = "sessions_stats_per_app"; pub const SESSIONS_STATS_BASE_KEYS: [(&'static str, bool); 4] = [ @@ -18,7 +17,7 @@ impl Db { &self, app_id: &str, filter: TimeFilter, - ) -> Result, Error> { + ) -> Result, DbError> { let start_date = filter.to_date(); let bucket_size = filter.bucket_size(); @@ -27,8 +26,7 @@ impl Db { "1 hour" => "hourly", "1 day" => "daily", "1 month" => "monthly", - // TODO for now return WorkerCrashed but later create custom error - _ => return Err(Error::WorkerCrashed), + _ => return Err(DbError::DatabaseError("Invalid bucket size".to_string())), }; let formatted_keys = format_view_keys(prefix, &SESSIONS_STATS_BASE_KEYS); @@ -48,6 +46,7 @@ impl Db { .bind(start_date) .fetch_all(&self.connection_pool) .await + .map_err(|e| e.into()) } } diff --git a/database/src/tables/client_profiles/select.rs b/database/src/tables/client_profiles/select.rs index b0f487c0..e7a65cd0 100644 --- a/database/src/tables/client_profiles/select.rs +++ b/database/src/tables/client_profiles/select.rs @@ -1,5 +1,6 @@ use super::table_struct::ClientProfile; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::client_profiles::table_struct::CLIENT_PROFILES_TABLE_NAME; use sqlx::query_as; @@ -7,7 +8,7 @@ impl Db { pub async fn get_profile_by_profile_id( &self, client_profile_id: i64, - ) -> Result { + ) -> Result { let query = format!("SELECT * FROM {CLIENT_PROFILES_TABLE_NAME} WHERE client_profile_id = $1"); let typed_query = query_as::<_, ClientProfile>(&query); @@ -15,6 +16,7 @@ impl Db { return typed_query .bind(&client_profile_id) .fetch_one(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/client_profiles/update.rs b/database/src/tables/client_profiles/update.rs index 09a090e9..eb0fc9ae 100644 --- a/database/src/tables/client_profiles/update.rs +++ b/database/src/tables/client_profiles/update.rs @@ -1,20 +1,25 @@ use super::table_struct::{CLIENT_PROFILES_KEYS, CLIENT_PROFILES_TABLE_NAME}; -use crate::{db::Db, tables::client_profiles::table_struct::ClientProfile}; +use crate::{ + db::Db, structs::db_error::DbError, tables::client_profiles::table_struct::ClientProfile, +}; use sqlx::{query_as, Transaction}; impl Db { pub async fn create_new_profile( &self, tx: Option<&mut Transaction<'_, sqlx::Postgres>>, - ) -> Result { + ) -> Result { let query_body = format!( "INSERT INTO {CLIENT_PROFILES_TABLE_NAME} ({CLIENT_PROFILES_KEYS}) VALUES (DEFAULT, DEFAULT) RETURNING {CLIENT_PROFILES_KEYS}" ); let typed_query = query_as::<_, ClientProfile>(&query_body); return match tx { - Some(tx) => typed_query.fetch_one(&mut **tx).await, - None => typed_query.fetch_one(&self.connection_pool).await, + Some(tx) => typed_query.fetch_one(&mut **tx).await.map_err(|e| e.into()), + None => typed_query + .fetch_one(&self.connection_pool) + .await + .map_err(|e| e.into()), }; } } diff --git a/database/src/tables/connection_events/select.rs b/database/src/tables/connection_events/select.rs index b64c97cc..0db47a80 100644 --- a/database/src/tables/connection_events/select.rs +++ b/database/src/tables/connection_events/select.rs @@ -1,5 +1,6 @@ use super::table_struct::ConnectionEvent; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::structs::entity_type::EntityType; use crate::structs::filter_requests::DistinctConnectedClient; use crate::tables::connection_events::table_struct::CONNECTION_EVENTS_TABLE_NAME; @@ -9,20 +10,21 @@ impl Db { pub async fn get_connection_events_by_session_id( &self, session_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {CONNECTION_EVENTS_TABLE_NAME} WHERE session_id = $1"); let typed_query = query_as::<_, ConnectionEvent>(&query); return typed_query .bind(&session_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_connection_events_by_client_profile_id( &self, client_profile_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT * FROM {CONNECTION_EVENTS_TABLE_NAME} WHERE entity_id = $1 AND entity_type = $2" ); @@ -32,26 +34,28 @@ impl Db { .bind(&client_profile_id) .bind(&EntityType::Client) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_connection_events_by_app_id( &self, app_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {CONNECTION_EVENTS_TABLE_NAME} WHERE app_id = $1"); let typed_query = query_as::<_, ConnectionEvent>(&query); return typed_query .bind(&app_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_connection_events_by_app( &self, app_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {CONNECTION_EVENTS_TABLE_NAME} WHERE entity_id = $1 AND entity_type = $2"); let typed_query = query_as::<_, ConnectionEvent>(&query); @@ -59,13 +63,14 @@ impl Db { .bind(&app_id) .bind(&EntityType::App) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_all_app_distinct_users( &self, app_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT pk.public_key, MIN(ce.connected_at) AS first_connection, MAX(ce.connected_at) AS last_connection FROM {CONNECTION_EVENTS_TABLE_NAME} ce @@ -78,6 +83,7 @@ impl Db { .bind(app_id) .bind(EntityType::Client) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/connection_events/update.rs b/database/src/tables/connection_events/update.rs index a0a86cf0..68d4d7d9 100644 --- a/database/src/tables/connection_events/update.rs +++ b/database/src/tables/connection_events/update.rs @@ -1,4 +1,5 @@ use crate::db::Db; +use crate::structs::db_error::DbError; use crate::structs::entity_type::EntityType; use crate::tables::connection_events::table_struct::{ CONNECTION_EVENTS_KEYS_KEYS, CONNECTION_EVENTS_TABLE_NAME, @@ -14,7 +15,7 @@ impl Db { connection_id: &String, app_id: &String, network: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {CONNECTION_EVENTS_TABLE_NAME} ({CONNECTION_EVENTS_KEYS_KEYS}) VALUES (DEFAULT, $1, $2, $3, $4, $5, $6, NOW(), NULL)" ); @@ -31,7 +32,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -42,7 +43,7 @@ impl Db { session_id: &String, client_profile_id: i64, network: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {CONNECTION_EVENTS_TABLE_NAME} ({CONNECTION_EVENTS_KEYS_KEYS}) VALUES (DEFAULT, $1, $2, NULL, $3, $4, $5, NOW(), NULL)" ); @@ -58,7 +59,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -68,7 +69,7 @@ impl Db { app_id: &String, connection_id: &String, session_id: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "UPDATE {CONNECTION_EVENTS_TABLE_NAME} SET disconnected_at = NOW() @@ -85,7 +86,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -95,7 +96,7 @@ impl Db { app_id: &String, session_id: &String, client_profile_id: i64, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "UPDATE {CONNECTION_EVENTS_TABLE_NAME} SET disconnected_at = NOW() @@ -112,7 +113,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/grafana_users/select.rs b/database/src/tables/grafana_users/select.rs index 9a416ab6..004dd597 100644 --- a/database/src/tables/grafana_users/select.rs +++ b/database/src/tables/grafana_users/select.rs @@ -1,29 +1,29 @@ use super::table_struct::GrafanaUser; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::grafana_users::table_struct::GRAFANA_USERS_TABLE_NAME; use sqlx::query_as; impl Db { - pub async fn get_user_by_user_id(&self, user_id: &String) -> Result { + pub async fn get_user_by_user_id(&self, user_id: &String) -> Result { let query = format!("SELECT * FROM {GRAFANA_USERS_TABLE_NAME} WHERE user_id = $1"); let typed_query = query_as::<_, GrafanaUser>(&query); return typed_query .bind(&user_id) .fetch_one(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } - pub async fn get_user_by_email( - &self, - email: &String, - ) -> Result, sqlx::Error> { + pub async fn get_user_by_email(&self, email: &String) -> Result, DbError> { let query = format!("SELECT * FROM {GRAFANA_USERS_TABLE_NAME} WHERE email = $1"); let typed_query = query_as::<_, GrafanaUser>(&query); return typed_query .bind(&email) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/grafana_users/update.rs b/database/src/tables/grafana_users/update.rs index e88257e1..e2184bd7 100644 --- a/database/src/tables/grafana_users/update.rs +++ b/database/src/tables/grafana_users/update.rs @@ -1,5 +1,6 @@ use super::table_struct::{GrafanaUser, GRAFANA_USERS_KEYS, GRAFANA_USERS_TABLE_NAME}; use crate::db::Db; +use crate::structs::db_error::DbError; use sqlx::query; use sqlx::Transaction; @@ -8,7 +9,7 @@ impl Db { &self, tx: &mut Transaction<'_, sqlx::Postgres>, user: &GrafanaUser, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {GRAFANA_USERS_TABLE_NAME} ({GRAFANA_USERS_KEYS}) VALUES ($1, $2, $3, $4)" ); @@ -23,11 +24,11 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } - pub async fn add_new_user(&self, user: &GrafanaUser) -> Result<(), sqlx::Error> { + pub async fn add_new_user(&self, user: &GrafanaUser) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {GRAFANA_USERS_TABLE_NAME} ({GRAFANA_USERS_KEYS}) VALUES ($1, $2, $3, $4)" ); @@ -42,7 +43,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/public_keys/select.rs b/database/src/tables/public_keys/select.rs index 63c35a20..92ff7549 100644 --- a/database/src/tables/public_keys/select.rs +++ b/database/src/tables/public_keys/select.rs @@ -1,16 +1,18 @@ use super::table_struct::PublicKey; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::public_keys::table_struct::PUBLIC_KEYS_TABLE_NAME; use sqlx::query_as; impl Db { - pub async fn get_public_key(&self, public_key: &String) -> Result { + pub async fn get_public_key(&self, public_key: &String) -> Result { let query = format!("SELECT * FROM {PUBLIC_KEYS_TABLE_NAME} WHERE public_key = $1"); let typed_query = query_as::<_, PublicKey>(&query); return typed_query .bind(&public_key) .fetch_one(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/public_keys/update.rs b/database/src/tables/public_keys/update.rs index f4ddf92c..0e2e6c4d 100644 --- a/database/src/tables/public_keys/update.rs +++ b/database/src/tables/public_keys/update.rs @@ -1,4 +1,5 @@ use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::client_profiles::table_struct::ClientProfile; use crate::tables::public_keys::table_struct::{ PublicKey, PUBLIC_KEYS_KEYS, PUBLIC_KEYS_TABLE_NAME, @@ -11,7 +12,7 @@ impl Db { &self, mut tx: &mut Transaction<'_, Postgres>, public_keys: &Vec, - ) -> Result<(i64, String), sqlx::Error> { + ) -> Result<(i64, String), DbError> { // Always take the first key as the reference key. let public_key = &public_keys[0]; @@ -45,7 +46,7 @@ impl Db { tx: &mut Transaction<'_, Postgres>, public_key: &String, client_profile: &ClientProfile, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {PUBLIC_KEYS_TABLE_NAME} ({PUBLIC_KEYS_KEYS}) VALUES ($1, $2, $3, $4)" ); @@ -60,7 +61,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -68,13 +69,17 @@ impl Db { &self, tx: &mut Transaction<'_, Postgres>, public_key: &String, - ) -> Result { + ) -> Result { let query = format!( "UPDATE {PUBLIC_KEYS_TABLE_NAME} SET last_seen = NOW() WHERE public_key = $1 RETURNING {PUBLIC_KEYS_KEYS}" ); let typed_query = query_as::<_, PublicKey>(&query); - return typed_query.bind(public_key).fetch_one(&mut **tx).await; + return typed_query + .bind(public_key) + .fetch_one(&mut **tx) + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/registered_app/select.rs b/database/src/tables/registered_app/select.rs index 48c02d0e..23757317 100644 --- a/database/src/tables/registered_app/select.rs +++ b/database/src/tables/registered_app/select.rs @@ -1,4 +1,5 @@ use super::table_struct::{DbRegisteredApp, REGISTERED_APPS_TABLE_NAME}; +use crate::structs::db_error::DbError; use crate::tables::requests::table_struct::REQUESTS_TABLE_NAME; use crate::{db::Db, tables::requests::table_struct::Request}; use sqlx::query_as; @@ -7,20 +8,18 @@ impl Db { pub async fn get_registered_app_by_app_id( &self, app_id: &String, - ) -> Result { + ) -> Result { let query = format!("SELECT * FROM {REGISTERED_APPS_TABLE_NAME} WHERE app_id = $1"); let typed_query = query_as::<_, DbRegisteredApp>(&query); return typed_query .bind(&app_id) .fetch_one(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } - pub async fn get_requests_by_app_id( - &self, - app_id: &String, - ) -> Result, sqlx::Error> { + pub async fn get_requests_by_app_id(&self, app_id: &String) -> Result, DbError> { let query = format!( "SELECT r.* FROM {REQUESTS_TABLE_NAME} r INNER JOIN sessions s ON r.session_id = s.session_id @@ -32,14 +31,15 @@ impl Db { return typed_query .bind(&app_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_registered_app_by_app_name_and_team_id( &self, app_name: &String, team_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT * FROM {REGISTERED_APPS_TABLE_NAME} WHERE app_name = $1 AND team_id = $2" ); @@ -49,6 +49,7 @@ impl Db { .bind(&app_name) .bind(&team_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/registered_app/update.rs b/database/src/tables/registered_app/update.rs index af51a6f3..3b9f5707 100644 --- a/database/src/tables/registered_app/update.rs +++ b/database/src/tables/registered_app/update.rs @@ -1,9 +1,9 @@ use super::table_struct::{DbRegisteredApp, REGISTERED_APPS_KEYS, REGISTERED_APPS_TABLE_NAME}; -use crate::db::Db; +use crate::{db::Db, structs::db_error::DbError}; use sqlx::{query, Transaction}; impl Db { - pub async fn register_new_app(&self, app: &DbRegisteredApp) -> Result<(), sqlx::Error> { + pub async fn register_new_app(&self, app: &DbRegisteredApp) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {REGISTERED_APPS_TABLE_NAME} ({REGISTERED_APPS_KEYS}) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)" ); @@ -22,7 +22,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -30,7 +30,7 @@ impl Db { &self, tx: &mut Transaction<'_, sqlx::Postgres>, app: &DbRegisteredApp, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {REGISTERED_APPS_TABLE_NAME} ({}) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", REGISTERED_APPS_KEYS @@ -50,7 +50,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/requests/select.rs b/database/src/tables/requests/select.rs index 92761eac..ddca4cb5 100644 --- a/database/src/tables/requests/select.rs +++ b/database/src/tables/requests/select.rs @@ -1,31 +1,33 @@ use super::table_struct::{Request, REQUESTS_TABLE_NAME}; -use crate::db::Db; +use crate::{db::Db, structs::db_error::DbError}; use sqlx::query_as; impl Db { pub async fn get_requests_by_session_id( &self, session_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {REQUESTS_TABLE_NAME} WHERE session_id = $1 ORDER BY creation_timestamp DESC"); let typed_query = query_as::<_, Request>(&query); return typed_query .bind(&session_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_request_by_request_id( &self, request_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {REQUESTS_TABLE_NAME} WHERE request_id = $1"); let typed_query = query_as::<_, Request>(&query); return typed_query .bind(&request_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/requests/update.rs b/database/src/tables/requests/update.rs index 797dbd55..600c9960 100644 --- a/database/src/tables/requests/update.rs +++ b/database/src/tables/requests/update.rs @@ -1,9 +1,12 @@ use super::table_struct::{Request, REQUESTS_KEYS, REQUESTS_TABLE_NAME}; -use crate::{db::Db, structs::request_status::RequestStatus}; +use crate::{ + db::Db, + structs::{db_error::DbError, request_status::RequestStatus}, +}; use sqlx::query; impl Db { - pub async fn save_request(&self, request: &Request) -> Result<(), sqlx::Error> { + pub async fn save_request(&self, request: &Request) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {REQUESTS_TABLE_NAME} ({}) VALUES ($1, $2, $3, $4, $5, $6, $7)", REQUESTS_KEYS @@ -22,7 +25,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -30,7 +33,7 @@ impl Db { &self, request_id: &String, new_status: &RequestStatus, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!("UPDATE {REQUESTS_TABLE_NAME} SET request_status = $1 WHERE request_id = $2"); let query_result = query(&query_body) @@ -41,7 +44,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/session_public_keys/select.rs b/database/src/tables/session_public_keys/select.rs index 34665ac2..33401914 100644 --- a/database/src/tables/session_public_keys/select.rs +++ b/database/src/tables/session_public_keys/select.rs @@ -1,4 +1,5 @@ use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::session_public_keys::table_struct::SessionPublicKey; use crate::tables::session_public_keys::table_struct::SESSION_PUBLIC_KEYS_TABLE_NAME; use sqlx::query_as; @@ -7,13 +8,14 @@ impl Db { pub async fn get_session_public_keys( &self, session_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {SESSION_PUBLIC_KEYS_TABLE_NAME} WHERE session_id = $1"); let typed_query = query_as::<_, SessionPublicKey>(&query); return typed_query .bind(&session_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/session_public_keys/update.rs b/database/src/tables/session_public_keys/update.rs index 93de6c92..c211a4d5 100644 --- a/database/src/tables/session_public_keys/update.rs +++ b/database/src/tables/session_public_keys/update.rs @@ -1,4 +1,5 @@ use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::session_public_keys::table_struct::{ SESSION_PUBLIC_KEYS_KEYS, SESSION_PUBLIC_KEYS_TABLE_NAME, }; @@ -13,7 +14,7 @@ impl Db { public_key: String, client_profile_id: Option, main_session_key: bool, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {SESSION_PUBLIC_KEYS_TABLE_NAME} ({SESSION_PUBLIC_KEYS_KEYS}) VALUES (DEFAULT, $1, $2, $3, $4, DEFAULT)" ); @@ -28,7 +29,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/sessions/select.rs b/database/src/tables/sessions/select.rs index a9772370..7401e87f 100644 --- a/database/src/tables/sessions/select.rs +++ b/database/src/tables/sessions/select.rs @@ -1,5 +1,6 @@ use super::table_struct::{DbNcSession, SESSIONS_TABLE_NAME}; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::requests::table_struct::{Request, REQUESTS_TABLE_NAME}; use sqlx::query_as; @@ -7,39 +8,39 @@ impl Db { pub async fn get_sessions_by_app_id( &self, app_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {SESSIONS_TABLE_NAME} WHERE app_id = $1 ORDER BY session_open_timestamp DESC"); let typed_query = query_as::<_, DbNcSession>(&query); return typed_query .bind(&app_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_session_by_session_id( &self, session_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {SESSIONS_TABLE_NAME} WHERE session_id = $1"); let typed_query = query_as::<_, DbNcSession>(&query); return typed_query .bind(&session_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } - pub async fn get_session_requests( - &self, - session_id: &String, - ) -> Result, sqlx::Error> { + pub async fn get_session_requests(&self, session_id: &String) -> Result, DbError> { let query = format!("SELECT * FROM {REQUESTS_TABLE_NAME} WHERE session_id = $1"); let typed_query = query_as::<_, Request>(&query); return typed_query .bind(&session_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/sessions/update.rs b/database/src/tables/sessions/update.rs index cc70ce88..2ae6038e 100644 --- a/database/src/tables/sessions/update.rs +++ b/database/src/tables/sessions/update.rs @@ -1,5 +1,8 @@ use super::table_struct::{DbNcSession, SESSIONS_KEYS, SESSIONS_TABLE_NAME}; -use crate::{db::Db, structs::client_data::ClientData}; +use crate::{ + db::Db, + structs::{client_data::ClientData, db_error::DbError}, +}; use log::error; use sqlx::{ query, @@ -12,7 +15,7 @@ impl Db { &self, session: &DbNcSession, connection_id: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let mut tx = self.connection_pool.begin().await.unwrap(); // 1. Save the new session @@ -51,7 +54,7 @@ impl Db { &self, tx: &mut Transaction<'_, Postgres>, session: &DbNcSession, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {SESSIONS_TABLE_NAME} ({}) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)", SESSIONS_KEYS @@ -78,7 +81,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -86,7 +89,7 @@ impl Db { &self, session_id: &String, close_timestamp: DateTime, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "UPDATE {SESSIONS_TABLE_NAME} SET session_close_timestamp = $1 WHERE session_id = $2" ); @@ -99,7 +102,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -110,14 +113,15 @@ impl Db { app_id: &String, session_id: &String, network: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { // Start a new transaction let mut tx = self.connection_pool.begin().await.unwrap(); // User can't connect to the session without any connected keys if connected_keys.is_empty() { - // TODO for now return this error, replace with a custom error - return Err(sqlx::Error::RowNotFound); + return Err(DbError::DatabaseError( + "No connected keys provided".to_string(), + )); } // 1. Handle connected keys @@ -156,7 +160,7 @@ impl Db { .rollback() .await .map_err(|err| error!("Failed to rollback transaction: {:?}", err)); - return Err(err); + return Err(err).map_err(|e| e.into()); } // 3. Create new session public key entry for each connected key diff --git a/database/src/tables/team/select.rs b/database/src/tables/team/select.rs index 353c318a..04d2a0aa 100644 --- a/database/src/tables/team/select.rs +++ b/database/src/tables/team/select.rs @@ -1,4 +1,5 @@ use super::table_struct::Team; +use crate::structs::db_error::DbError; use crate::tables::registered_app::table_struct::REGISTERED_APPS_TABLE_NAME; use crate::tables::team::table_struct::TEAM_TABLE_NAME; use crate::{db::Db, tables::registered_app::table_struct::DbRegisteredApp}; @@ -9,17 +10,24 @@ impl Db { &self, tx: Option<&mut Transaction<'_, sqlx::Postgres>>, team_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {TEAM_TABLE_NAME} WHERE team_id = $1"); let typed_query = query_as::<_, Team>(&query); match tx { - Some(tx) => return typed_query.bind(&team_id).fetch_optional(&mut **tx).await, + Some(tx) => { + return typed_query + .bind(&team_id) + .fetch_optional(&mut **tx) + .await + .map_err(|e| e.into()) + } None => { return typed_query .bind(&team_id) .fetch_optional(&self.connection_pool) .await + .map_err(|e| e.into()) } } } @@ -27,7 +35,7 @@ impl Db { pub async fn get_registered_apps_by_team_id( &self, team_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT r.* FROM {REGISTERED_APPS_TABLE_NAME} r INNER JOIN team t ON r.team_id = t.team_id @@ -39,13 +47,14 @@ impl Db { return typed_query .bind(&team_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_user_created_teams_without_personal( &self, admin_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT * FROM {TEAM_TABLE_NAME} WHERE team_admin_id = $1 AND personal = false" ); @@ -54,13 +63,14 @@ impl Db { return typed_query .bind(&admin_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_personal_team_by_admin_id( &self, admin_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {TEAM_TABLE_NAME} WHERE team_admin_id = $1 AND personal = true"); let typed_query = query_as::<_, Team>(&query); @@ -68,14 +78,15 @@ impl Db { return typed_query .bind(&admin_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_team_by_team_name_and_admin_id( &self, team_name: &String, team_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {TEAM_TABLE_NAME} WHERE team_name = $1 AND team_id = $2"); let typed_query = query_as::<_, Team>(&query); @@ -84,19 +95,18 @@ impl Db { .bind(&team_name) .bind(&team_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } - pub async fn get_team_by_admin_id( - &self, - admin_id: &String, - ) -> Result, sqlx::Error> { + pub async fn get_team_by_admin_id(&self, admin_id: &String) -> Result, DbError> { let query = format!("SELECT * FROM {TEAM_TABLE_NAME} WHERE team_admin_id = $1"); let typed_query = query_as::<_, Team>(&query); return typed_query .bind(&admin_id) .fetch_optional(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/team/update.rs b/database/src/tables/team/update.rs index d1065ebe..b3298fa0 100644 --- a/database/src/tables/team/update.rs +++ b/database/src/tables/team/update.rs @@ -1,7 +1,7 @@ use super::table_struct::TEAM_KEYS; use crate::{ db::Db, - structs::subscription::Subscription, + structs::{db_error::DbError, subscription::Subscription}, tables::team::table_struct::{Team, TEAM_TABLE_NAME}, }; use sqlx::{query, Transaction}; @@ -11,7 +11,7 @@ impl Db { &self, tx: &mut Transaction<'_, sqlx::Postgres>, team: &Team, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!("INSERT INTO {TEAM_TABLE_NAME} ({TEAM_KEYS}) VALUES ($1, $2, $3, $4, $5, $6)"); @@ -27,11 +27,11 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } - pub async fn create_new_team(&self, team: &Team) -> Result<(), sqlx::Error> { + pub async fn create_new_team(&self, team: &Team) -> Result<(), DbError> { let query_body = format!("INSERT INTO {TEAM_TABLE_NAME} ({TEAM_KEYS}) VALUES ($1, $2, $3, $4, $5, $6)"); @@ -47,7 +47,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -55,7 +55,7 @@ impl Db { &self, team_id: &String, subscription: &Subscription, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!("UPDATE {TEAM_TABLE_NAME} SET subscription = $1 WHERE team_id = $2"); let query_result = query(&query_body) @@ -66,7 +66,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } } diff --git a/database/src/tables/test_utils.rs b/database/src/tables/test_utils.rs index cb6c7f4e..7106abe4 100644 --- a/database/src/tables/test_utils.rs +++ b/database/src/tables/test_utils.rs @@ -2,7 +2,7 @@ pub mod test_utils { use crate::{ db::Db, - structs::privilege_level::PrivilegeLevel, + structs::{db_error::DbError, privilege_level::PrivilegeLevel}, tables::{ grafana_users::table_struct::GrafanaUser, registered_app::table_struct::DbRegisteredApp, team::table_struct::Team, @@ -15,7 +15,7 @@ pub mod test_utils { }; impl Db { - pub async fn truncate_all_tables(&self) -> Result<(), sqlx::Error> { + pub async fn truncate_all_tables(&self) -> Result<(), DbError> { let rows = sqlx::query( "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'", ) @@ -59,7 +59,7 @@ pub mod test_utils { pub async fn refresh_continuous_aggregates( &self, views: Vec, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { // Refresh views for view in views.iter() { let _ = sqlx::query(&format!( @@ -80,7 +80,7 @@ pub mod test_utils { team_id: &String, app_id: &String, registration_timestamp: DateTime, - ) -> anyhow::Result<()> { + ) -> Result<(), DbError> { let admin = GrafanaUser { creation_timestamp: registration_timestamp, email: "email".to_string(), diff --git a/database/src/tables/user_app_privileges/select.rs b/database/src/tables/user_app_privileges/select.rs index f44e132d..ba28cf42 100644 --- a/database/src/tables/user_app_privileges/select.rs +++ b/database/src/tables/user_app_privileges/select.rs @@ -1,5 +1,6 @@ use super::table_struct::UserAppPrivilege; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::tables::registered_app::table_struct::REGISTERED_APPS_TABLE_NAME; use crate::tables::user_app_privileges::table_struct::USER_APP_PRIVILEGES_TABLE_NAME; use sqlx::query_as; @@ -9,7 +10,7 @@ impl Db { &self, user_id: &String, app_id: &String, - ) -> Result { + ) -> Result { let query = format!( "SELECT * FROM {USER_APP_PRIVILEGES_TABLE_NAME} WHERE user_id = $1 AND app_id = $2" ); @@ -19,40 +20,43 @@ impl Db { .bind(&user_id) .bind(&app_id) .fetch_one(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_privileges_by_user_id( &self, user_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {USER_APP_PRIVILEGES_TABLE_NAME} WHERE user_id = $1"); let typed_query = query_as::<_, UserAppPrivilege>(&query); return typed_query .bind(&user_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_privileges_by_app_id( &self, app_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!("SELECT * FROM {USER_APP_PRIVILEGES_TABLE_NAME} WHERE app_id = $1"); let typed_query = query_as::<_, UserAppPrivilege>(&query); return typed_query .bind(&app_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } // Get all privileges for a team pub async fn get_privileges_by_team_id( &self, team_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT uap.* FROM {USER_APP_PRIVILEGES_TABLE_NAME} uap JOIN {REGISTERED_APPS_TABLE_NAME} ra ON uap.app_id = ra.app_id @@ -64,13 +68,14 @@ impl Db { return typed_query .bind(team_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } pub async fn get_teams_and_apps_membership_by_user_id( &self, user_id: &String, - ) -> Result, sqlx::Error> { + ) -> Result, DbError> { let query = format!( "SELECT ra.team_id, ra.app_id FROM {USER_APP_PRIVILEGES_TABLE_NAME} uap JOIN {REGISTERED_APPS_TABLE_NAME} ra ON uap.app_id = ra.app_id @@ -81,6 +86,7 @@ impl Db { return typed_query .bind(user_id) .fetch_all(&self.connection_pool) - .await; + .await + .map_err(|e| e.into()); } } diff --git a/database/src/tables/user_app_privileges/update.rs b/database/src/tables/user_app_privileges/update.rs index cbbbe4c4..c72649e8 100644 --- a/database/src/tables/user_app_privileges/update.rs +++ b/database/src/tables/user_app_privileges/update.rs @@ -2,6 +2,7 @@ use std::collections::HashSet; use super::table_struct::UserAppPrivilege; use crate::db::Db; +use crate::structs::db_error::DbError; use crate::structs::privilege_level::PrivilegeLevel; use crate::tables::registered_app::table_struct::REGISTERED_APPS_TABLE_NAME; use crate::tables::user_app_privileges::table_struct::{ @@ -16,7 +17,7 @@ impl Db { &self, tx: &mut Transaction<'_, sqlx::Postgres>, privilege: &UserAppPrivilege, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {USER_APP_PRIVILEGES_TABLE_NAME} ({USER_APP_PRIVILEGES_KEYS}) VALUES ($1, $2, $3, $4)" ); @@ -31,11 +32,11 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } - pub async fn add_new_privilege(&self, privilege: &UserAppPrivilege) -> Result<(), sqlx::Error> { + pub async fn add_new_privilege(&self, privilege: &UserAppPrivilege) -> Result<(), DbError> { let query_body = format!( "INSERT INTO {USER_APP_PRIVILEGES_TABLE_NAME} ({USER_APP_PRIVILEGES_KEYS}) VALUES ($1, $2, $3, $4)" ); @@ -50,7 +51,7 @@ impl Db { match query_result { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(e).map_err(|e| e.into()), } } @@ -58,7 +59,7 @@ impl Db { &self, user_id: &String, team_id: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { // Retrieve all apps associated with the team let apps_query = format!("SELECT app_id FROM {REGISTERED_APPS_TABLE_NAME} WHERE team_id = $1"); @@ -72,8 +73,9 @@ impl Db { // Only proceed if there are apps to assign privileges for if apps.is_empty() { - // TODO, add custom error type - return Err(sqlx::Error::RowNotFound); + return Err(DbError::DatabaseError( + "No apps associated with the team".to_string(), + )); } // Build values list for insertion @@ -109,7 +111,7 @@ impl Db { team_id: &String, team_admin_id: &String, app_id: &String, - ) -> Result<(), sqlx::Error> { + ) -> Result<(), DbError> { // Get all users that are part of the team let users_privileges_query = self.get_privileges_by_team_id(team_id).await?; let mut users_ids_list = users_privileges_query From 8af6d24a41d8d25bf93f7b1aa8905952228dbf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CGiems=E2=80=9D?= <“hubert.wabia@gmail.com”> Date: Thu, 7 Mar 2024 15:11:59 +0100 Subject: [PATCH 3/3] remove import --- database/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/database/Cargo.toml b/database/Cargo.toml index 13d2a61f..56c6f408 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -11,5 +11,4 @@ serde = { workspace = true } ts-rs = { workspace = true } tokio = { workspace = true } dotenvy = { workspace = true } -anyhow = { workspace = true } log = { workspace = true } \ No newline at end of file