Skip to content

Commit

Permalink
fix: Handle Interrupted Error
Browse files Browse the repository at this point in the history
Rust may throw Interrupted errors while scanning filesystem. These may
be retried:
https://doc.rust-lang.org/std/io/enum.ErrorKind.html#variant.Interrupted
  • Loading branch information
bootandy committed Jan 25, 2025
1 parent 9ba0b6d commit 2ee998c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
60 changes: 43 additions & 17 deletions src/dir_walker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::cmp::Ordering;
use std::fs;
use std::io::Error;
use std::sync::Arc;
use std::sync::Mutex;

Expand Down Expand Up @@ -178,8 +179,8 @@ fn ignore_file(entry: &DirEntry, walk_data: &WalkData) -> bool {

fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
let prog_data = &walk_data.progress_data;
let errors = &walk_data.errors;

let errors = &walk_data.errors;
if errors.lock().unwrap().abort {
return None;
}
Expand Down Expand Up @@ -229,30 +230,21 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
}
}
Err(ref failed) => {
let mut editable_error = errors.lock().unwrap();
editable_error.no_permissions.insert(failed.to_string());
if handle_error_and_retry(failed, &dir, walk_data) {
return walk(dir.clone(), walk_data, depth);
}
}
}
None
})
.collect()
}
Err(failed) => {
let mut editable_error = errors.lock().unwrap();
match failed.kind() {
std::io::ErrorKind::PermissionDenied => {
editable_error
.no_permissions
.insert(dir.to_string_lossy().into());
}
std::io::ErrorKind::NotFound => {
editable_error.file_not_found.insert(failed.to_string());
}
_ => {
editable_error.unknown_error.insert(failed.to_string());
}
if handle_error_and_retry(&failed, &dir, walk_data) {
return walk(dir, walk_data, depth);
} else {
vec![]
}
vec![]
}
}
} else {
Expand All @@ -274,6 +266,40 @@ fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
build_node(dir, children, is_symlink, false, depth, walk_data)
}

fn handle_error_and_retry(failed: &Error, dir: &PathBuf, walk_data: &WalkData) -> bool {
let mut editable_error = walk_data.errors.lock().unwrap();
match failed.kind() {
std::io::ErrorKind::PermissionDenied => {
editable_error
.no_permissions
.insert(dir.to_string_lossy().into());
}
std::io::ErrorKind::InvalidInput => {
editable_error
.no_permissions
.insert(dir.to_string_lossy().into());
}
std::io::ErrorKind::NotFound => {
editable_error.file_not_found.insert(failed.to_string());
}
std::io::ErrorKind::Interrupted => {
let mut editable_error = walk_data.errors.lock().unwrap();
editable_error.interruped_error += 1;

Check warning on line 287 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 287 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".

Check warning on line 287 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 287 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".
if editable_error.interruped_error > 3 {

Check warning on line 288 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 288 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".

Check warning on line 288 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 288 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".
panic!("Multiple Interrupted Errors occured while scanning filesystem. Aborting");

Check warning on line 289 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"occured" should be "occurred".

Check warning on line 289 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"occured" should be "occurred".

Check warning on line 289 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"occured" should be "occurred".

Check warning on line 289 in src/dir_walker.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"occured" should be "occurred".
} else {
return true;
}
}
_ => {
println!("{:?} {:?}", failed, dir);
println!("FISH");
editable_error.unknown_error.insert(failed.to_string());
}
}
false
}

mod tests {

#[allow(unused_imports)]
Expand Down
1 change: 1 addition & 0 deletions src/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub struct RuntimeErrors {
pub no_permissions: HashSet<String>,
pub file_not_found: HashSet<String>,
pub unknown_error: HashSet<String>,
pub interruped_error: i32,

Check warning on line 81 in src/progress.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 81 in src/progress.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".

Check warning on line 81 in src/progress.rs

View workflow job for this annotation

GitHub Actions / Style (ubuntu-latest)

"interruped" should be "interrupted".

Check warning on line 81 in src/progress.rs

View workflow job for this annotation

GitHub Actions / Style (macos-latest)

"interruped" should be "interrupted".
pub abort: bool,
}

Expand Down

0 comments on commit 2ee998c

Please sign in to comment.