From 841e6a34a49261d2681c8a4d2c1dc176ba4e3b35 Mon Sep 17 00:00:00 2001 From: Ben Morrison Date: Tue, 26 May 2020 23:15:51 -0400 Subject: removed panics and refactored error handling Using a helper function to handle fatal errors error::helper() Displays the simplified message if an error condition occurs. Displays both the simplified and the raw error message if -v verbose logging is enabled. --- src/db.rs | 29 ++++++++++++++----------- src/ed.rs | 21 ++++++++---------- src/error.rs | 20 ++++++++---------- src/logging.rs | 10 +-------- src/main.rs | 67 +++++++++++++++++++--------------------------------------- src/posts.rs | 3 +++ 6 files changed, 61 insertions(+), 89 deletions(-) diff --git a/src/db.rs b/src/db.rs index 935f1f9..84f209b 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,7 @@ use std::time; use crate::conf; +use crate::error; const DB_PATH: &str = "/usr/local/clinte/clinte.db"; @@ -25,24 +26,28 @@ impl Conn { log::info!("Connecting to database"); } - let conn = rusqlite::Connection::open_with_flags( - path, - rusqlite::OpenFlags::SQLITE_OPEN_FULL_MUTEX - | rusqlite::OpenFlags::SQLITE_OPEN_CREATE - | rusqlite::OpenFlags::SQLITE_OPEN_READ_WRITE, - ) - .expect("Could not connect to DB"); + let conn = error::helper( + rusqlite::Connection::open_with_flags( + path, + rusqlite::OpenFlags::SQLITE_OPEN_FULL_MUTEX + | rusqlite::OpenFlags::SQLITE_OPEN_CREATE + | rusqlite::OpenFlags::SQLITE_OPEN_READ_WRITE, + ), + "Could not connect to DB", + ); - conn.execute( - "CREATE TABLE IF NOT EXISTS posts ( + error::helper( + conn.execute( + "CREATE TABLE IF NOT EXISTS posts ( id INTEGER PRIMARY KEY NOT NULL, title TEXT NOT NULL, author TEXT NOT NULL, body TEXT NOT NULL )", - rusqlite::NO_PARAMS, - ) - .expect("Could not initialize DB"); + rusqlite::NO_PARAMS, + ), + "Could not initialize DB", + ); if *conf::DEBUG { log::info!( diff --git a/src/ed.rs b/src/ed.rs index 31a27ae..095fd9a 100644 --- a/src/ed.rs +++ b/src/ed.rs @@ -4,22 +4,15 @@ use std::process; use chrono::prelude::*; -use crate::conf; use crate::error; use crate::user; -fn create_tmp_file<'a>() -> Result { +fn create_tmp_file<'a>() -> Result { let the_time = Utc::now().to_rfc3339(); let file_name = format!("/tmp/clinte_ed_{}_{}", *user::NAME, the_time); match fs::write(&file_name, "") { Ok(_) => Ok(file_name), - Err(err) => { - log::warn!("Couldn't create tempfile"); - if *conf::DEBUG { - log::warn!("--> {:?}", err); - } - Err("Unable to create temp file") - } + Err(err) => Err(err), } } @@ -40,7 +33,7 @@ pub fn call() -> String { } }; - let tmp_loc = error::helper(create_tmp_file()); + let tmp_loc = error::helper(create_tmp_file(), "Couldn't create tempfile"); error::helper( process::Command::new(editor) @@ -48,9 +41,13 @@ pub fn call() -> String { .stdin(process::Stdio::inherit()) .stdout(process::Stdio::inherit()) .output(), + "Couldn't call editor", ); - let body = error::helper(fs::read_to_string(&tmp_loc)); - error::helper(fs::remove_file(tmp_loc)); + let body = error::helper( + fs::read_to_string(&tmp_loc), + "Couldn't read message from disk", + ); + error::helper(fs::remove_file(tmp_loc), "Couldn't remove temporary file"); body } diff --git a/src/error.rs b/src/error.rs index 517b5fc..aa21021 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,15 +1,20 @@ +use crate::conf; + // This Result is used elsewhere, not in helper() pub type Result = std::result::Result>; -pub fn helper(res: std::result::Result) -> T +pub fn helper(res: std::result::Result, simplified_message: &str) -> T where V: std::fmt::Debug, { match res { Ok(val) => val, Err(err) => { - log::error!("{:?}", err); - panic!("{:?}", err); + log::error!("{}", simplified_message); + if *conf::DEBUG { + log::error!("--> {:?}", err); + } + std::process::exit(1); } } } @@ -21,14 +26,7 @@ mod tests { #[test] fn shouldnt_panic() { let ok: std::result::Result<&str, &str> = Ok("okay"); - let rhs = helper(ok); + let rhs = helper(ok, "okay"); assert_eq!("okay", rhs); } - - #[test] - #[should_panic] - fn should_panic() { - let err: std::result::Result<&str, &str> = Err("oops"); - helper(err); - } } diff --git a/src/logging.rs b/src/logging.rs index 5d3f378..d748117 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -2,20 +2,12 @@ use std::fs::OpenOptions; use simplelog::*; -use crate::conf; use crate::error; use crate::user; pub fn checked_init() { let logfile = format!("/tmp/clinte_{}.log", *user::NAME); - - if let Err(e) = init(&logfile) { - log::error!("Couldn't initialize logging. Exiting."); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); - } + error::helper(init(&logfile), "Couldn't initialize logging"); } fn init(path: &str) -> error::Result<()> { diff --git a/src/main.rs b/src/main.rs index 8b6cb9a..06fb4ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,63 +29,40 @@ fn main() { if arg_matches.subcommand_matches("post").is_some() { log::info!("New post..."); - if let Err(e) = posts::create(&db) { - log::error!("Error creating new post"); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); - } + error::helper(posts::create(&db), "Error creating new post"); } else if arg_matches.subcommand_matches("update").is_some() { let id: u32 = if let Some(val) = arg_matches.subcommand_matches("update_handler") { - match val.value_of("id").unwrap_or_else(|| "0").parse() { - Ok(n) => n, - Err(e) => { - log::error!("Couldn't parse ID"); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); - } - } + error::helper( + val.value_of("id").unwrap_or_else(|| "0").parse(), + "Couldn't parse ID", + ) } else { 0 }; + log::info!("Updating post ..."); - if let Err(e) = posts::update_handler(&db, id) { - log::error!("Error updating post {}", id); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); - } + + error::helper( + posts::update_handler(&db, id), + format!("Error updating post {}", id).as_ref(), + ); } else if arg_matches.subcommand_matches("delete").is_some() { let id: u32 = if let Some(val) = arg_matches.subcommand_matches("update_handler") { - match val.value_of("id").unwrap_or_else(|| "0").parse() { - Ok(n) => n, - Err(_) => { - log::error!("Couldn't parse ID"); - std::process::exit(1); - } - } + error::helper( + val.value_of("id").unwrap_or_else(|| "0").parse(), + "Couldn't parse ID", + ) } else { 0 }; + log::info!("Deleting post"); - if let Err(e) = posts::delete_handler(&db, id) { - log::error!("Error deleting post {}", id); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); - } - } - if let Err(e) = posts::display(&db) { - log::error!("Error displaying posts"); - if *conf::DEBUG { - log::error!("--> {}", e); - } - std::process::exit(1); + error::helper( + posts::delete_handler(&db, id), + format!("Error deleting post {}", id).as_ref(), + ); } + + error::helper(posts::display(&db), "Error displaying posts"); } diff --git a/src/posts.rs b/src/posts.rs index e019454..be95533 100644 --- a/src/posts.rs +++ b/src/posts.rs @@ -38,8 +38,10 @@ pub fn create(db: &db::Conn) -> error::Result<()> { println!(); println!("Title of the new post: "); + let mut title = String::new(); io::stdin().read_line(&mut title)?; + let title = str_to_utf8(title.trim()); let title = if title.len() > 30 { &title[..30] @@ -48,6 +50,7 @@ pub fn create(db: &db::Conn) -> error::Result<()> { }; println!(); + let body_raw = str_to_utf8(&ed::call()); let body = if body_raw.len() > 500 { &body_raw[..500] -- cgit 1.4.1-2-gfad0