From de7954483eb0ce6daeba6eb06e8ed91a7b0e1dfb Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 23 May 2020 23:02:28 -0400 Subject: include filenames in the error messages about file operations --- src/config.rs | 47 +++++++++++++++++------------- src/db.rs | 72 ++++++++++++++++++++++++++-------------------- src/dirs.rs | 15 ++++++---- src/error.rs | 91 ++++++++++++++++++++++++++++++++++++++++++----------------- 4 files changed, 143 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/config.rs b/src/config.rs index d5c1659..418da45 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,13 +33,16 @@ impl Config { } pub fn load() -> Result { - let mut fh = std::fs::File::open(crate::dirs::config_file()) - .context(crate::error::LoadConfig)?; + let file = crate::dirs::config_file(); + let mut fh = std::fs::File::open(&file).with_context(|| { + crate::error::LoadConfig { file: file.clone() } + })?; let mut json = String::new(); - fh.read_to_string(&mut json) - .context(crate::error::LoadConfig)?; + fh.read_to_string(&mut json).with_context(|| { + crate::error::LoadConfig { file: file.clone() } + })?; let mut slf: Self = serde_json::from_str(&json) - .context(crate::error::LoadConfigJson)?; + .context(crate::error::LoadConfigJson { file })?; if slf.lock_timeout == 0 { log::warn!("lock_timeout must be greater than 0"); slf.lock_timeout = default_lock_timeout(); @@ -48,15 +51,17 @@ impl Config { } pub async fn load_async() -> Result { - let mut fh = tokio::fs::File::open(crate::dirs::config_file()) - .await - .context(crate::error::LoadConfigAsync)?; + let file = crate::dirs::config_file(); + let mut fh = + tokio::fs::File::open(&file).await.with_context(|| { + crate::error::LoadConfigAsync { file: file.clone() } + })?; let mut json = String::new(); - fh.read_to_string(&mut json) - .await - .context(crate::error::LoadConfigAsync)?; + fh.read_to_string(&mut json).await.with_context(|| { + crate::error::LoadConfigAsync { file: file.clone() } + })?; let mut slf: Self = serde_json::from_str(&json) - .context(crate::error::LoadConfigJson)?; + .context(crate::error::LoadConfigJson { file })?; if slf.lock_timeout == 0 { log::warn!("lock_timeout must be greater than 0"); slf.lock_timeout = default_lock_timeout(); @@ -65,19 +70,23 @@ impl Config { } pub fn save(&self) -> Result<()> { - let filename = crate::dirs::config_file(); + let file = crate::dirs::config_file(); // unwrap is safe here because Self::filename is explicitly // constructed as a filename in a directory - std::fs::create_dir_all(filename.parent().unwrap()) - .context(crate::error::SaveConfig)?; - let mut fh = std::fs::File::create(filename) - .context(crate::error::SaveConfig)?; + std::fs::create_dir_all(file.parent().unwrap()).with_context( + || crate::error::SaveConfig { file: file.clone() }, + )?; + let mut fh = std::fs::File::create(&file).with_context(|| { + crate::error::SaveConfig { file: file.clone() } + })?; fh.write_all( serde_json::to_string(self) - .context(crate::error::SaveConfigJson)? + .with_context(|| crate::error::SaveConfigJson { + file: file.clone(), + })? .as_bytes(), ) - .context(crate::error::SaveConfig)?; + .context(crate::error::SaveConfig { file })?; Ok(()) } diff --git a/src/db.rs b/src/db.rs index 324e7a5..c695577 100644 --- a/src/db.rs +++ b/src/db.rs @@ -83,77 +83,87 @@ impl Db { } pub fn load(server: &str, email: &str) -> Result { - let mut fh = std::fs::File::open(crate::dirs::db_file(server, email)) - .context(crate::error::LoadDb)?; + let file = crate::dirs::db_file(server, email); + let mut fh = std::fs::File::open(&file) + .with_context(|| crate::error::LoadDb { file: file.clone() })?; let mut json = String::new(); - fh.read_to_string(&mut json).context(crate::error::LoadDb)?; - let slf: Self = - serde_json::from_str(&json).context(crate::error::LoadDbJson)?; + fh.read_to_string(&mut json) + .with_context(|| crate::error::LoadDb { file: file.clone() })?; + let slf: Self = serde_json::from_str(&json) + .context(crate::error::LoadDbJson { file })?; Ok(slf) } pub async fn load_async(server: &str, email: &str) -> Result { + let file = crate::dirs::db_file(server, email); let mut fh = - tokio::fs::File::open(crate::dirs::db_file(server, email)) - .await - .context(crate::error::LoadDbAsync)?; + tokio::fs::File::open(&file).await.with_context(|| { + crate::error::LoadDbAsync { file: file.clone() } + })?; let mut json = String::new(); - fh.read_to_string(&mut json) - .await - .context(crate::error::LoadDbAsync)?; - let slf: Self = - serde_json::from_str(&json).context(crate::error::LoadDbJson)?; + fh.read_to_string(&mut json).await.with_context(|| { + crate::error::LoadDbAsync { file: file.clone() } + })?; + let slf: Self = serde_json::from_str(&json) + .context(crate::error::LoadDbJson { file })?; Ok(slf) } // XXX need to make this atomic pub fn save(&self, server: &str, email: &str) -> Result<()> { - let filename = crate::dirs::db_file(server, email); + let file = crate::dirs::db_file(server, email); // unwrap is safe here because Self::filename is explicitly // constructed as a filename in a directory - std::fs::create_dir_all(filename.parent().unwrap()) - .context(crate::error::SaveDb)?; - let mut fh = - std::fs::File::create(filename).context(crate::error::SaveDb)?; + std::fs::create_dir_all(file.parent().unwrap()) + .with_context(|| crate::error::SaveDb { file: file.clone() })?; + let mut fh = std::fs::File::create(&file) + .with_context(|| crate::error::SaveDb { file: file.clone() })?; fh.write_all( serde_json::to_string(self) - .context(crate::error::SaveDbJson)? + .with_context(|| crate::error::SaveDbJson { + file: file.clone(), + })? .as_bytes(), ) - .context(crate::error::SaveDb)?; + .context(crate::error::SaveDb { file })?; Ok(()) } // XXX need to make this atomic pub async fn save_async(&self, server: &str, email: &str) -> Result<()> { - let filename = crate::dirs::db_file(server, email); + let file = crate::dirs::db_file(server, email); // unwrap is safe here because Self::filename is explicitly // constructed as a filename in a directory - tokio::fs::create_dir_all(filename.parent().unwrap()) - .await - .context(crate::error::SaveDbAsync)?; - let mut fh = tokio::fs::File::create(filename) + tokio::fs::create_dir_all(file.parent().unwrap()) .await - .context(crate::error::SaveDbAsync)?; + .with_context(|| crate::error::SaveDbAsync { + file: file.clone(), + })?; + let mut fh = + tokio::fs::File::create(&file).await.with_context(|| { + crate::error::SaveDbAsync { file: file.clone() } + })?; fh.write_all( serde_json::to_string(self) - .context(crate::error::SaveDbJson)? + .with_context(|| crate::error::SaveDbJson { + file: file.clone(), + })? .as_bytes(), ) .await - .context(crate::error::SaveDbAsync)?; + .context(crate::error::SaveDbAsync { file })?; Ok(()) } pub fn remove(server: &str, email: &str) -> Result<()> { - let filename = crate::dirs::db_file(server, email); - let res = std::fs::remove_file(filename); + let file = crate::dirs::db_file(server, email); + let res = std::fs::remove_file(&file); if let Err(e) = &res { if e.kind() == std::io::ErrorKind::NotFound { return Ok(()); } } - res.context(crate::error::RemoveDb)?; + res.context(crate::error::RemoveDb { file })?; Ok(()) } diff --git a/src/dirs.rs b/src/dirs.rs index 53a433e..fa063b8 100644 --- a/src/dirs.rs +++ b/src/dirs.rs @@ -1,14 +1,17 @@ use crate::prelude::*; pub fn make_all() -> Result<()> { - std::fs::create_dir_all(&cache_dir()) - .context(crate::error::CreateDirectory)?; + let cache_dir = cache_dir(); + std::fs::create_dir_all(&cache_dir) + .context(crate::error::CreateDirectory { file: cache_dir })?; - std::fs::create_dir_all(&runtime_dir()) - .context(crate::error::CreateDirectory)?; + let runtime_dir = runtime_dir(); + std::fs::create_dir_all(&runtime_dir) + .context(crate::error::CreateDirectory { file: runtime_dir })?; - std::fs::create_dir_all(&data_dir()) - .context(crate::error::CreateDirectory)?; + let data_dir = data_dir(); + std::fs::create_dir_all(&data_dir) + .context(crate::error::CreateDirectory { file: data_dir })?; Ok(()) } diff --git a/src/error.rs b/src/error.rs index 418aa3a..3030079 100644 --- a/src/error.rs +++ b/src/error.rs @@ -9,8 +9,11 @@ pub enum Error { source: block_modes::InvalidKeyIvLength, }, - #[snafu(display("failed to create directory"))] - CreateDirectory { source: std::io::Error }, + #[snafu(display("failed to create directory at {}", file.display()))] + CreateDirectory { + source: std::io::Error, + file: std::path::PathBuf, + }, #[snafu(display("failed to decrypt"))] Decrypt { source: block_modes::BlockModeError }, @@ -51,23 +54,41 @@ pub enum Error { source: serde_path_to_error::Error, }, - #[snafu(display("failed to load config"))] - LoadConfig { source: std::io::Error }, + #[snafu(display("failed to load config from {}", file.display()))] + LoadConfig { + source: std::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to load config"))] - LoadConfigAsync { source: tokio::io::Error }, + #[snafu(display("failed to load config from {}", file.display()))] + LoadConfigAsync { + source: tokio::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to load config"))] - LoadConfigJson { source: serde_json::Error }, + #[snafu(display("failed to load config from {}", file.display()))] + LoadConfigJson { + source: serde_json::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to load db"))] - LoadDb { source: std::io::Error }, + #[snafu(display("failed to load db from {}", file.display()))] + LoadDb { + source: std::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to load db"))] - LoadDbAsync { source: tokio::io::Error }, + #[snafu(display("failed to load db from {}", file.display()))] + LoadDbAsync { + source: tokio::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to load db"))] - LoadDbJson { source: serde_json::Error }, + #[snafu(display("failed to load db from {}", file.display()))] + LoadDbJson { + source: serde_json::Error, + file: std::path::PathBuf, + }, #[snafu(display("openssl error"))] OpenSSL { source: openssl::error::ErrorStack }, @@ -87,8 +108,11 @@ pub enum Error { #[snafu(display("error waiting for pinentry to exit"))] PinentryWait { source: tokio::io::Error }, - #[snafu(display("failed to remove db"))] - RemoveDb { source: std::io::Error }, + #[snafu(display("failed to remove db at {}", file.display()))] + RemoveDb { + source: std::io::Error, + file: std::path::PathBuf, + }, #[snafu(display("api request returned error: {}", status))] RequestFailed { status: u16 }, @@ -99,20 +123,35 @@ pub enum Error { #[snafu(display("error making api request"))] Reqwest { source: reqwest::Error }, - #[snafu(display("failed to save config"))] - SaveConfig { source: std::io::Error }, + #[snafu(display("failed to save config to {}", file.display()))] + SaveConfig { + source: std::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to save config"))] - SaveConfigJson { source: serde_json::Error }, + #[snafu(display("failed to save config to {}", file.display()))] + SaveConfigJson { + source: serde_json::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to save db"))] - SaveDb { source: std::io::Error }, + #[snafu(display("failed to save db to {}", file.display()))] + SaveDb { + source: std::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to save db"))] - SaveDbAsync { source: tokio::io::Error }, + #[snafu(display("failed to save db to {}", file.display()))] + SaveDbAsync { + source: tokio::io::Error, + file: std::path::PathBuf, + }, - #[snafu(display("failed to save db"))] - SaveDbJson { source: serde_json::Error }, + #[snafu(display("failed to save db to {}", file.display()))] + SaveDbJson { + source: serde_json::Error, + file: std::path::PathBuf, + }, #[snafu(display("error spawning pinentry"))] Spawn { source: tokio::io::Error }, -- cgit v1.2.3-54-g00ecf