diff --git a/src/imex.rs b/src/imex.rs index e77f7baa3..6bf804c15 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -700,20 +700,16 @@ async fn export_self_keys(context: &Context, dir: &Path) -> Result<()> { for (id, public_key, private_key, is_default) in keys { let id = Some(id).filter(|_| is_default != 0); if let Ok(key) = public_key { - if export_key_to_asc_file(context, dir, id, &key) - .await - .is_err() - { + if let Err(err) = export_key_to_asc_file(context, dir, id, &key).await { + error!(context, "Failed to export public key: {:#}.", err); export_errors += 1; } } else { export_errors += 1; } if let Ok(key) = private_key { - if export_key_to_asc_file(context, dir, id, &key) - .await - .is_err() - { + if let Err(err) = export_key_to_asc_file(context, dir, id, &key).await { + error!(context, "Failed to export private key: {:#}.", err); export_errors += 1; } } else { @@ -733,7 +729,7 @@ async fn export_key_to_asc_file( dir: &Path, id: Option, key: &T, -) -> std::io::Result<()> +) -> Result<()> where T: DcKey + Any, { @@ -755,16 +751,16 @@ where key.key_id(), file_name.display() ); - delete_file(context, &file_name).await; + + // Delete the file if it already exists. + delete_file(context, &file_name).await.ok(); let content = key.to_asc(None).into_bytes(); - let res = write_file(context, &file_name, &content).await; - if res.is_err() { - error!(context, "Cannot write key to {}", file_name.display()); - } else { - context.emit_event(EventType::ImexFileWritten(file_name)); - } - res + write_file(context, &file_name, &content) + .await + .with_context(|| format!("cannot write key to {}", file_name.display()))?; + context.emit_event(EventType::ImexFileWritten(file_name)); + Ok(()) } #[cfg(test)] @@ -854,12 +850,12 @@ mod tests { let context = TestContext::new_alice().await; let blobdir = context.ctx.get_blobdir(); if let Err(err) = imex(&context.ctx, ImexMode::ExportSelfKeys, blobdir, None).await { - panic!("got error on export: {:?}", err); + panic!("got error on export: {:#}", err); } let context2 = TestContext::new_alice().await; if let Err(err) = imex(&context2.ctx, ImexMode::ImportSelfKeys, blobdir, None).await { - panic!("got error on import: {:?}", err); + panic!("got error on import: {:#}", err); } } diff --git a/src/sql.rs b/src/sql.rs index 493948cf9..58665b65f 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -798,7 +798,14 @@ pub async fn remove_unused_files(context: &Context) -> Result<()> { entry.file_name() ); let path = entry.path(); - delete_file(context, path).await; + if let Err(err) = delete_file(context, &path).await { + error!( + context, + "Failed to delete unused file {}: {:#}.", + path.display(), + err + ); + } } } Err(err) => { diff --git a/src/tools.rs b/src/tools.rs index fa96710e7..9bfab1490 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; use std::str::from_utf8; use std::time::{Duration, SystemTime}; -use anyhow::{bail, Result}; +use anyhow::{bail, Context as _, Result}; use chrono::{Local, TimeZone}; use futures::{StreamExt, TryStreamExt}; use mailparse::dateparse; @@ -369,49 +369,39 @@ pub(crate) async fn get_filebytes(context: &Context, path: impl AsRef) -> Ok(meta.len()) } -pub(crate) async fn delete_file(context: &Context, path: impl AsRef) -> bool { - let path_abs = get_abs_path(context, &path); +pub(crate) async fn delete_file(context: &Context, path: impl AsRef) -> Result<()> { + let path = path.as_ref(); + let path_abs = get_abs_path(context, path); if !path_abs.exists() { - return false; + bail!("path {} does not exist", path_abs.display()); } if !path_abs.is_file() { - warn!( - context, - "refusing to delete non-file \"{}\".", - path.as_ref().display() - ); - return false; + warn!(context, "refusing to delete non-file {}.", path.display()); + bail!("not a file: \"{}\"", path.display()); } - let dpath = format!("{}", path.as_ref().to_string_lossy()); - match fs::remove_file(path_abs).await { - Ok(_) => { - context.emit_event(EventType::DeletedBlobFile(dpath)); - true - } - Err(err) => { - warn!(context, "Cannot delete \"{}\": {}", dpath, err); - false - } - } + let dpath = format!("{}", path.to_string_lossy()); + fs::remove_file(path_abs) + .await + .with_context(|| format!("cannot delete {:?}", dpath))?; + context.emit_event(EventType::DeletedBlobFile(dpath)); + Ok(()) } -pub async fn delete_files_in_dir(context: &Context, path: impl AsRef) { - match tokio::fs::read_dir(path).await { - Ok(read_dir) => { - let mut read_dir = tokio_stream::wrappers::ReadDirStream::new(read_dir); - while let Some(entry) = read_dir.next().await { - match entry { - Ok(file) => { - delete_file(context, file.file_name()).await; - } - Err(e) => warn!(context, "Could not read file to delete: {}", e), - } +pub async fn delete_files_in_dir(context: &Context, path: impl AsRef) -> Result<()> { + let read_dir = tokio::fs::read_dir(path) + .await + .context("could not read dir to delete")?; + let mut read_dir = tokio_stream::wrappers::ReadDirStream::new(read_dir); + while let Some(entry) = read_dir.next().await { + match entry { + Ok(file) => { + delete_file(context, file.file_name()).await?; } + Err(e) => warn!(context, "Could not read file to delete: {}", e), } - - Err(e) => warn!(context, "Could not read dir to delete: {}", e), } + Ok(()) } pub(crate) async fn create_folder( @@ -1047,7 +1037,9 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; }; } - assert!(!delete_file(context, "$BLOBDIR/lkqwjelqkwlje").await); + assert!(delete_file(context, "$BLOBDIR/lkqwjelqkwlje") + .await + .is_err()); assert!(write_file(context, "$BLOBDIR/foobar", b"content") .await .is_ok()); @@ -1063,17 +1055,19 @@ DKIM Results: Passed=true, Works=true, Allow_Keychange=true"; assert!(file_exist!(context, &abs_path)); - assert!(delete_file(context, "$BLOBDIR/foobar").await); + assert!(delete_file(context, "$BLOBDIR/foobar").await.is_ok()); assert!(create_folder(context, "$BLOBDIR/foobar-folder") .await .is_ok()); assert!(file_exist!(context, "$BLOBDIR/foobar-folder")); - assert!(!delete_file(context, "$BLOBDIR/foobar-folder").await); + assert!(delete_file(context, "$BLOBDIR/foobar-folder") + .await + .is_err()); let fn0 = "$BLOBDIR/data.data"; assert!(write_file(context, &fn0, b"content").await.is_ok()); - assert!(delete_file(context, &fn0).await); + assert!(delete_file(context, &fn0).await.is_ok()); assert!(!file_exist!(context, &fn0)); }