From cafb3d45b8bca291ac14b5252a822b803342d1e4 Mon Sep 17 00:00:00 2001 From: clawbot Date: Sun, 8 Feb 2026 08:34:17 -0800 Subject: [PATCH] fix: track and report file restore failures Restore previously logged errors for individual files but returned success even if files failed. Now tracks failed files in RestoreResult, reports them in the summary output, and returns an error if any files failed to restore. Fixes #21 --- internal/vaultik/restore.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/vaultik/restore.go b/internal/vaultik/restore.go index aa00a27..d56fcca 100644 --- a/internal/vaultik/restore.go +++ b/internal/vaultik/restore.go @@ -118,6 +118,8 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error { if err := v.restoreFile(v.ctx, repos, file, opts.TargetDir, identity, chunkToBlobMap, blobCache, result); err != nil { log.Error("Failed to restore file", "path", file.Path, "error", err) + result.FilesFailed++ + result.FailedFiles = append(result.FailedFiles, file.Path.String()) // Continue with other files continue } @@ -147,6 +149,13 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error { result.Duration.Round(time.Second), ) + if result.FilesFailed > 0 { + _, _ = fmt.Fprintf(v.Stdout, "\nWARNING: %d file(s) failed to restore:\n", result.FilesFailed) + for _, path := range result.FailedFiles { + _, _ = fmt.Fprintf(v.Stdout, " - %s\n", path) + } + } + // Run verification if requested if opts.Verify { if err := v.verifyRestoredFiles(v.ctx, repos, files, opts.TargetDir, result); err != nil { @@ -167,6 +176,10 @@ func (v *Vaultik) Restore(opts *RestoreOptions) error { ) } + if result.FilesFailed > 0 { + return fmt.Errorf("%d file(s) failed to restore", result.FilesFailed) + } + return nil }