feat: add thiserror for error handling

This commit is contained in:
Alexander Navarro 2025-01-21 11:43:59 -03:00
parent 07861bcca9
commit e65afb8553
4 changed files with 27 additions and 7 deletions

1
Cargo.lock generated
View file

@ -1391,6 +1391,7 @@ dependencies = [
"clap", "clap",
"futures", "futures",
"sqlx", "sqlx",
"thiserror",
"tokio", "tokio",
] ]

View file

@ -14,4 +14,5 @@ sqlx = { version = "0.8", features = [
"sqlite", "sqlite",
"chrono", "chrono",
] } ] }
tokio = {version = "1.43.0", features = ["full"]} thiserror = "2.0.11"
tokio = { version = "1.43.0", features = ["full"] }

View file

@ -2,6 +2,7 @@
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use futures::TryStreamExt; use futures::TryStreamExt;
use simple_crud::error::Result;
use simple_crud::sql::ColumnType; use simple_crud::sql::ColumnType;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use sqlx::Column; use sqlx::Column;
@ -21,7 +22,7 @@ struct Cli {
#[derive(Subcommand)] #[derive(Subcommand)]
enum Commands { enum Commands {
/// Executes a query agains the database, it pass it directly to the underliying driver /// Executes a query against the database, it pass it directly to the underlying driver
Query { Query {
/// Query to execute /// Query to execute
sql: String, sql: String,
@ -29,7 +30,7 @@ enum Commands {
} }
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> Result<()> {
let cli = Cli::parse(); let cli = Cli::parse();
let url = cli.db_url.unwrap(); let url = cli.db_url.unwrap();
@ -37,18 +38,20 @@ async fn main() {
// You can check for the existence of subcommands, and if found use their // You can check for the existence of subcommands, and if found use their
// matches just as you would the top level cmd // matches just as you would the top level cmd
match &cli.command { match &cli.command {
Commands::Query { sql } => handle_query(url, sql).await.unwrap(), Commands::Query { sql } => handle_query(url, sql).await?,
} }
Ok(())
} }
async fn handle_query(url: String, query: &String) -> Result<(), sqlx::Error> { async fn handle_query(url: String, query: &String) -> Result<()> {
let pool = PgPool::connect(url.as_str()).await?; let pool = PgPool::connect(url.as_str()).await?;
let mut rows = sqlx::query(query.as_str()).fetch(&pool); let mut rows = sqlx::query(query.as_str()).fetch(&pool);
while let Some(row) = rows.try_next().await? { while let Some(row) = rows.try_next().await? {
for idx in 0..row.len() { for idx in 0..row.len() {
let column = ColumnType::new(&row, idx).unwrap(); let column = ColumnType::new(&row, idx)?;
// let value = String::from(row.get(col.ordinal())); // let value = String::from(row.get(col.ordinal()));
println!("Column {:?}", column); println!("Column {:?}", column);
} }

View file

@ -1 +1,16 @@
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>; pub type Result<T> = std::result::Result<T, Error>;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Unhandled error: {0}")]
Generic(String),
#[error("Unhandled error: {0}")]
Static(&'static str),
#[error(transparent)]
IO(#[from] std::io::Error),
#[error("Error performing database operation.")]
DatabaseOperation(#[from] sqlx::Error),
}