fix(scanner): store scan errors in the database and update UI error handling

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan
2026-02-01 16:16:58 +01:00
parent 84ab652ca7
commit ebbc31f1ab
5 changed files with 67 additions and 21 deletions
+4
View File
@@ -224,6 +224,10 @@ func (s *controller) ScanFolders(requestCtx context.Context, fullScan bool, targ
for _, w := range scanWarnings {
log.Warn(ctx, fmt.Sprintf("Scan warning: %s", w))
}
// Store scan error in database so it can be displayed in the UI
if scanError != nil {
_ = s.ds.Property(ctx).Put(consts.LastScanErrorKey, scanError.Error())
}
// If changes were detected, send a refresh event to all clients
if s.changesDetected {
log.Debug(ctx, "Library changes imported. Sending refresh event")
+1 -1
View File
@@ -40,7 +40,7 @@ func createPhaseFolders(ctx context.Context, state *scanState, ds model.DataStor
job, err := newScanJob(ctx, ds, cw, lib, state.fullScan, targetFolders)
if err != nil {
log.Error(ctx, "Scanner: Error creating scan context", "lib", lib.Name, err)
state.sendWarning(err.Error())
state.sendError(err)
continue
}
jobs = append(jobs, job)
+7 -1
View File
@@ -51,8 +51,14 @@ var _ = Describe("Scanner - Multi-Library", Ordered, func() {
BeforeEach(func() {
DeferCleanup(configtest.SetupConfig())
conf.Server.MusicFolder = "default:///music" // Use a distinct schema for the default library
conf.Server.DevExternalScanner = false
// Register an empty fake storage for the default library
emptyFS := storagetest.FakeFS{}
emptyFS.SetFiles(fstest.MapFS{})
storagetest.Register("default", &emptyFS)
db.Init(ctx)
DeferCleanup(func() {
Expect(tests.ClearDB()).To(Succeed())
@@ -770,7 +776,7 @@ var _ = Describe("Scanner - Multi-Library", Ordered, func() {
// Second scan should recover and import all rock content
warnings, err = s.ScanAll(ctx, true)
Expect(err).ToNot(HaveOccurred())
Expect(warnings).ToNot(BeEmpty(), "Should have warnings for temporary disk error")
Expect(warnings).To(BeEmpty(), "Should have no warnings after error recovery")
// Verify both libraries now have content (at least jazz should work)
rockFiles, err := ds.MediaFile(ctx).GetAll(model.QueryOptions{