Skip to content

PathList::sanitize() aborts the whole backup if any path is missing — needs a skip-missing mode #504

@arcker

Description

@arcker

Summary

PathList::sanitize() calls canonicalize() on every path. If a single path doesn't exist on disk, the function returns an error and the entire backup is aborted, dropping all the other paths the user wanted to back up.

Reproduce

let pathlist: PathList = vec![PathBuf::from(r"C:\real-folder"), PathBuf::from(r"C:\does-not-exist")]
    .into_iter()
    .collect();
let pathlist = pathlist.sanitize()?;
// Err: Os { code: 123, kind: InvalidFilename }
// `C:\real-folder` is never backed up either.

Why it's a problem

For consumers that generate the path list dynamically — game-save backup tools (Ludusavi-driven, like our project), folder-of-folders backups, OneDrive-not-yet-synced cases, etc. — it's normal for some entries to be missing. The current behavior forces every caller to pre-filter p.exists() before calling sanitize(), which is easy to forget and surprising.

Suggestion

Either:

pub fn sanitize_skip_missing(self) -> SnapshotFileResult<(Self, Vec<PathBuf>)>;
// returns (sanitized_pathlist, paths_dropped_because_missing)

…or a flag on BackupOptions:

pub struct BackupOptions {
    /// If true, source paths that don't exist on disk are silently skipped
    /// rather than aborting the backup.
    pub skip_missing_paths: bool,
    // ...
}

Workaround

Pre-filter on p.exists() before constructing the PathList. We log a warning per skipped path so the user knows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    S-triageStatus: Waiting for a maintainer to triage this issue/PR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions