Skip to content

Commit

Permalink
Custom error impl
Browse files Browse the repository at this point in the history
  • Loading branch information
pawurb committed Sep 24, 2024
1 parent ebdb91e commit 15bcd63
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 21 deletions.
15 changes: 8 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ readme = "README.md"
repository = "https://github.com/pawurb/rust-pg-extras"
version = "0.3.2"

exclude = [
"docker-compose.yml.sample",
"live_tests.sh",
]
exclude = ["docker-compose.yml.sample", "live_tests.sh"]

[dependencies]
prettytable-rs = "0.10"
sqlx = {version = "0.6", features = ["runtime-tokio-rustls", "postgres", "macros", "bigdecimal"]}
thiserror = "1.0"
tokio = {version = "1", features = ["full"]}
sqlx = { version = "0.6", features = [
"runtime-tokio-rustls",
"postgres",
"macros",
"bigdecimal",
] }
tokio = { version = "1", features = ["full"] }

[[bin]]
name = "pg_extras"
Expand Down
35 changes: 27 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::env;
use std::time::Duration;
use std::{env, fmt};
pub mod queries;
pub use queries::all_locks::AllLocks;
pub use queries::bloat::Bloat;
Expand Down Expand Up @@ -36,7 +37,6 @@ pub use queries::total_table_size::TotalTableSize;
pub use queries::unused_indexes::UnusedIndexes;
pub use queries::vacuum_stats::VacuumStats;
use sqlx::postgres::PgPoolOptions;
use thiserror::Error;

#[macro_use]
extern crate prettytable;
Expand Down Expand Up @@ -204,17 +204,32 @@ pub async fn db_settings() -> Result<Vec<DbSettings>, PgExtrasError> {
get_rows(None).await
}

#[derive(Error, Debug)]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum PgExtrasError {
#[error("Both $DATABASE_URL and $PG_EXTRAS_DATABASE_URL are not set.")]
MissingConfigVars(),
#[error("Cannot connect to database: '{0}'")]
DbConnectionError(String),
#[error("Unknown pg-extras error: '{0}'")]
Unknown(String),
}

impl fmt::Display for PgExtrasError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match self {
Self::MissingConfigVars() => {
"Both $DATABASE_URL and $PG_EXTRAS_DATABASE_URL are not set.".to_string()
}
Self::DbConnectionError(e) => {
format!("Cannot connect to database: '{}'", e)
}
Self::Unknown(e) => format!("Unknown pg-extras error: '{}'", e),
};

write!(f, "{}", msg)
}
}

impl std::error::Error for PgExtrasError {}

async fn get_rows<T: Query>(
params: Option<HashMap<String, String>>,
) -> Result<Vec<T>, PgExtrasError> {
Expand All @@ -228,6 +243,7 @@ async fn get_rows<T: Query>(

let pool = match PgPoolOptions::new()
.max_connections(5)
.acquire_timeout(Duration::from_secs(10))
.connect(db_url()?.as_str())
.await
{
Expand Down Expand Up @@ -265,11 +281,14 @@ fn limit_params(limit: Option<String>) -> HashMap<String, String> {

#[cfg(test)]
mod tests {
use std::time::Duration;

use super::*;

async fn setup() -> Result<(), Box<dyn std::error::Error>> {
let pool = PgPoolOptions::new()
.max_connections(5)
.acquire_timeout(Duration::from_secs(10))
.connect(db_url()?.as_str())
.await?;

Expand Down Expand Up @@ -322,10 +341,10 @@ mod tests {
Ok(())
}

fn is_normal<T: Sized + Send + Sync + Unpin>() {}

#[test]
fn normal_types() {
fn is_normal<T: Sized + Send + Sync + Unpin>() {}

is_normal::<NullIndexes>();
is_normal::<Bloat>();
is_normal::<Blocking>();
Expand Down
34 changes: 28 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use pg_extras::{
vacuum_stats, PgExtrasError,
};

use std::env;
use thiserror::Error;
use std::{env, fmt};

#[tokio::main]
async fn main() {
Expand Down Expand Up @@ -136,19 +135,42 @@ async fn execute(command: Option<&String>) -> Result<(), PgExtrasCmdError> {
Ok(())
}

#[derive(Error, Debug)]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum PgExtrasCmdError {
#[error("Unknown command '{0}'. Check https://github.com/pawurb/rust-pg-extras for list of available commands.")]
UnknownCommand(String),
#[error("Missing command. Check https://github.com/pawurb/rust-pg-extras for list of available commands.")]
MissingCommand,
#[error("{0}")]
Other(PgExtrasError),
}

impl fmt::Display for PgExtrasCmdError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let check_command_text =
"Check https://github.com/pawurb/rust-pg-extras for list of available commands.";

let msg = match self {
Self::UnknownCommand(command) => {
format!("Unknown command '{}'. {}", command, check_command_text)
}
Self::MissingCommand => {
format!("Missing command. {}", check_command_text)
}
Self::Other(error) => format!("{}", error),
};
write!(f, "{}", msg)
}
}

impl From<pg_extras::PgExtrasError> for PgExtrasCmdError {
fn from(error: pg_extras::PgExtrasError) -> Self {
Self::Other(error)
}
}

impl std::error::Error for PgExtrasCmdError {}

#[test]
fn normal_types() {
fn is_normal<T: Sized + Send + Sync + Unpin>() {}
is_normal::<PgExtrasCmdError>();
}

0 comments on commit 15bcd63

Please sign in to comment.