fix(scanner): nil metadata_overrides crashed Reset to Scanned with SQLSTATE 23502
Reset to Scanned cleared the overrides row (successfully) but then set
the in-memory copy to nil before handing it to updateMediaItem. pgx
encodes a nil []string parameter as SQL NULL, so the follow-up UPDATE
wrote metadata_overrides = NULL into the column's NOT NULL constraint
and the whole rescan failed with:
failed to update media item: ERROR: null value in column
"metadata_overrides" of relation "media_items" violates not-null
constraint (SQLSTATE 23502)
Two changes:
- RescanMediaItem's reset path assigns []string{} instead of nil, with a
comment explaining the pgx nil-to-NULL encoding trap.
- updateMediaItem routes the override set through utils.MergeOverrides,
whose contract guarantees a non-nil slice, so no caller can write
NULL into that column again (verified against pgx v5.9.2 source: a
scanned '{}' round-trips as non-nil in both directions; the nil could
only come from our own assignment).
The plain Rescan path never hit this - only Reset did. Worse, the reset
is the remedy when a book's cover_image_path override pins an empty
cover, so the crash also blocked the way out of that state. After this
fix, a plain rescan on an already-reset book repopulates scanned
metadata and extracts the cover.
This commit is contained in:
@@ -2847,8 +2847,10 @@ func (s *MediaScanner) updateMediaItem(ctx context.Context, existing database.Me
|
||||
}
|
||||
|
||||
// Keep user-customized fields, and keep the override set itself intact.
|
||||
// MergeOverrides guarantees a non-nil slice: a nil []string would encode
|
||||
// as SQL NULL and violate metadata_overrides' NOT NULL constraint.
|
||||
utils.ApplyMetadataOverrides(¶ms, existing)
|
||||
params.MetadataOverrides = existing.MetadataOverrides
|
||||
params.MetadataOverrides = utils.MergeOverrides(existing.MetadataOverrides)
|
||||
|
||||
_, err = s.db.UpdateMediaItem(ctx, params)
|
||||
return err
|
||||
@@ -2869,7 +2871,10 @@ func (s *MediaScanner) RescanMediaItem(ctx context.Context, mediaItemID pgtype.U
|
||||
if err := s.db.ClearMediaItemMetadataOverrides(ctx, mediaItemID); err != nil {
|
||||
return fmt.Errorf("failed to clear metadata overrides: %w", err)
|
||||
}
|
||||
item.MetadataOverrides = nil
|
||||
// Empty - not nil: pgx encodes a nil []string parameter as SQL NULL,
|
||||
// which would violate the column's NOT NULL constraint when
|
||||
// updateMediaItem writes the row back.
|
||||
item.MetadataOverrides = []string{}
|
||||
}
|
||||
|
||||
folders, err := s.db.GetLibraryFolders(ctx, item.LibraryID)
|
||||
|
||||
Reference in New Issue
Block a user