diff --git a/src/filesystem.rs b/src/filesystem.rs index 74fc776..fddda77 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -80,11 +80,12 @@ pub async fn rescan_vault( type UpdatePathResult = Result; -#[derive(Debug, Clone)] +#[derive(Debug)] enum UpdatePathOutcome { Added(PathBuf), Unchanged(PathBuf), Removed(PathBuf), + Failed(PathBuf, Error), } fn _rescan_vault>( @@ -92,7 +93,7 @@ fn _rescan_vault>( directory: T, job_container: Arc>, job_id: JobId, -) -> Result> { +) -> Result> { let start = Instant::now(); info!("Vault rescan started."); @@ -123,16 +124,16 @@ fn _rescan_vault>( let count = RwLock::new(0_usize); let resolve_cache = Arc::new(Mutex::new(LruCache::new(256))); let total = path_entries.len() as f32; - let path_results: Vec = path_entries + let path_outcomes: Vec = path_entries .into_par_iter() .map(|path| { let result = _process_directory_entry( &rw_pool, &resolve_cache, - path, + path.clone(), &absolute_dir_path, &existing_files, - )?; + ); let mut cnt = count.write().unwrap(); *cnt += 1; @@ -143,35 +144,43 @@ fn _rescan_vault>( .update_progress(&job_id, *cnt as f32 / total * 100.0) .unwrap(); - Ok(result) + match result { + Ok(result) => result, + Err(error) => UpdatePathOutcome::Failed(path, error), + } }) .collect(); let existing_files = existing_files.read().unwrap(); + let connection = pool.get()?; let cleanup_results = existing_files.iter().filter(|f| f.valid).map(|file| { - let connection = pool.get()?; - connection.transaction::<_, Error, _>(|| { + let trans_result = connection.transaction::<_, Error, _>(|| { file_set_valid(&connection, file.id, false)?; // remove_object(&connection, )? - info!("Removed: {:?}", file.path); - Ok(UpdatePathOutcome::Removed(PathBuf::from(file.path.clone()))) - }) + Ok(()) + }); + + match trans_result { + Ok(_) => { + info!("Removed: {:?}", file.path); + UpdatePathOutcome::Removed(PathBuf::from(file.path.clone())) + } + Err(error) => UpdatePathOutcome::Failed(PathBuf::from(file.path.clone()), error), + } }); - let mut failed: Vec<&Error> = vec![]; + let mut failed: Vec<(&PathBuf, &Error)> = vec![]; let mut created = 0; let mut unchanged = 0; let mut deleted = 0; - for result in &path_results { - match result { - Ok(result) => match result { - UpdatePathOutcome::Added(_) => created += 1, - UpdatePathOutcome::Unchanged(_) => unchanged += 1, - UpdatePathOutcome::Removed(_) => deleted += 1, - }, - Err(err) => failed.push(err), + for outcome in &path_outcomes { + match outcome { + UpdatePathOutcome::Added(_) => created += 1, + UpdatePathOutcome::Unchanged(_) => unchanged += 1, + UpdatePathOutcome::Removed(_) => deleted += 1, + UpdatePathOutcome::Failed(path, err) => failed.push((path, err)), } } @@ -181,7 +190,7 @@ fn _rescan_vault>( failed.len(), failed .iter() - .map(|e| e.to_string()) + .map(|(path, error)| format!("{:?}: {}", path, error)) .collect::>() .join(", ") ) @@ -200,7 +209,7 @@ fn _rescan_vault>( start.elapsed().as_secs() ); - Ok(path_results.into_iter().chain(cleanup_results).collect()) + Ok(path_outcomes.into_iter().chain(cleanup_results).collect()) } fn _process_directory_entry>( @@ -396,11 +405,9 @@ mod test { assert!(rescan_result.is_ok()); let rescan_result = rescan_result.unwrap(); assert_eq!(rescan_result.len(), 3); - rescan_result.into_iter().for_each(|outcome| { - assert!(outcome.is_ok()); - let outcome = outcome.unwrap(); - assert!(matches!(outcome, UpdatePathOutcome::Added(_))) - }); + rescan_result + .into_iter() + .for_each(|outcome| assert!(matches!(outcome, UpdatePathOutcome::Added(_)))); // Modification-less rescan @@ -414,11 +421,9 @@ mod test { assert!(rescan_result.is_ok()); let rescan_result = rescan_result.unwrap(); assert_eq!(rescan_result.len(), 3); - rescan_result.into_iter().for_each(|outcome| { - assert!(outcome.is_ok()); - let outcome = outcome.unwrap(); - assert!(matches!(outcome, UpdatePathOutcome::Unchanged(_))) - }); + rescan_result + .into_iter() + .for_each(|outcome| assert!(matches!(outcome, UpdatePathOutcome::Unchanged(_)))); // Remove a file @@ -438,14 +443,14 @@ mod test { 2, rescan_result .iter() - .filter(|upo| matches!(upo.as_ref().unwrap(), UpdatePathOutcome::Unchanged(_))) + .filter(|upo| matches!(upo, UpdatePathOutcome::Unchanged(_))) .count() ); assert_eq!( 1, rescan_result .iter() - .filter(|upo| matches!(upo.as_ref().unwrap(), UpdatePathOutcome::Removed(_))) + .filter(|upo| matches!(upo, UpdatePathOutcome::Removed(_))) .count() ); }