From 3e7685adc23be7235d6d3c79ef2b48b683d74dfa Mon Sep 17 00:00:00 2001 From: Deluan Date: Tue, 21 Jul 2026 23:02:47 -0400 Subject: [PATCH] fix(artwork): never sweep files on transient DB errors during prune --- core/artwork/prune.go | 3 ++- core/artwork/prune_test.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/core/artwork/prune.go b/core/artwork/prune.go index 7d66bd8fe..931990056 100644 --- a/core/artwork/prune.go +++ b/core/artwork/prune.go @@ -2,6 +2,7 @@ package artwork import ( "context" + "errors" "time" "github.com/navidrome/navidrome/core/artwork/originals" @@ -36,7 +37,7 @@ func Prune(ctx context.Context, ds model.DataStore, store *originals.Store) erro removed, err := store.Sweep(func(hash string) bool { _, err := repo.Get(hash) - return err == nil + return !errors.Is(err, model.ErrNotFound) }) if err != nil { return err diff --git a/core/artwork/prune_test.go b/core/artwork/prune_test.go index ae6901da4..54564a170 100644 --- a/core/artwork/prune_test.go +++ b/core/artwork/prune_test.go @@ -3,6 +3,7 @@ package artwork import ( "bytes" "context" + "errors" "os" "time" @@ -13,6 +14,14 @@ import ( . "github.com/onsi/gomega" ) +type flakyGetArtworkRepo struct { + *tests.MockArtworkRepo +} + +func (f *flakyGetArtworkRepo) Get(string) (*model.Artwork, error) { + return nil, errors.New("db locked") +} + var _ = Describe("Prune", func() { var ds *tests.MockDataStore var store *originals.Store @@ -58,4 +67,18 @@ var _ = Describe("Prune", func() { _, err := store.Open(h, "image/jpeg") Expect(os.IsNotExist(err)).To(BeTrue()) }) + + It("never sweeps files on a transient DB error", func() { + ds.MockedArtwork = &flakyGetArtworkRepo{MockArtworkRepo: tests.CreateMockArtworkRepo()} + + data := []byte("live-bytes") + h, _ := originals.Hash(bytes.NewReader(data)) + Expect(store.Write(h, "image/jpeg", bytes.NewReader(data))).To(Succeed()) + + Expect(Prune(context.Background(), ds, store)).To(Succeed()) + + rc, err := store.Open(h, "image/jpeg") + Expect(err).ToNot(HaveOccurred()) + rc.Close() + }) })