Skip to content

Commit 0113ec4

Browse files
committed
Be resilient to most IO error and filesystem loop
Recover from IO errors wile walking directories, only abort when error from `walkdir` is without an path to recover.
1 parent 6f91278 commit 0113ec4

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

src/cargo/sources/path.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ impl<'cfg> PathSource<'cfg> {
340340
ret.extend(files.into_iter());
341341
}
342342
Err(..) => {
343-
PathSource::walk(&file_path, &mut ret, false, filter)?;
343+
self.walk(&file_path, &mut ret, false, filter)?;
344344
}
345345
}
346346
} else if filter(&file_path, is_dir) {
@@ -378,11 +378,12 @@ impl<'cfg> PathSource<'cfg> {
378378
filter: &mut dyn FnMut(&Path, bool) -> bool,
379379
) -> CargoResult<Vec<PathBuf>> {
380380
let mut ret = Vec::new();
381-
PathSource::walk(pkg.root(), &mut ret, true, filter)?;
381+
self.walk(pkg.root(), &mut ret, true, filter)?;
382382
Ok(ret)
383383
}
384384

385385
fn walk(
386+
&self,
386387
path: &Path,
387388
ret: &mut Vec<PathBuf>,
388389
is_root: bool,
@@ -420,9 +421,22 @@ impl<'cfg> PathSource<'cfg> {
420421
true
421422
});
422423
for entry in walkdir {
423-
let entry = entry?;
424-
if !entry.file_type().is_dir() {
425-
ret.push(entry.path().to_path_buf());
424+
match entry {
425+
Ok(entry) => {
426+
if !entry.file_type().is_dir() {
427+
ret.push(entry.into_path());
428+
}
429+
}
430+
Err(err) if err.loop_ancestor().is_some() => {
431+
self.config.shell().warn(err)?;
432+
}
433+
Err(err) => match err.path() {
434+
// If the error occurs with a path, simply recover from it.
435+
// Don't worry about error skipping here, the callers would
436+
// still hit the IO error if they do access it thereafter.
437+
Some(path) => ret.push(path.to_path_buf()),
438+
None => return Err(err.into()),
439+
},
426440
}
427441
}
428442

0 commit comments

Comments
 (0)