API: Improve logging in batch edit request handler #271

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2025-11-27 17:54:05 +01:00
parent c7ffcbc8df
commit 059e6baedf

View File

@@ -11,10 +11,12 @@ import (
"github.com/photoprism/photoprism/internal/entity" "github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/entity/query" "github.com/photoprism/photoprism/internal/entity/query"
"github.com/photoprism/photoprism/internal/entity/search" "github.com/photoprism/photoprism/internal/entity/search"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/photoprism/batch" "github.com/photoprism/photoprism/internal/photoprism/batch"
"github.com/photoprism/photoprism/internal/photoprism/get" "github.com/photoprism/photoprism/internal/photoprism/get"
"github.com/photoprism/photoprism/pkg/clean" "github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/i18n" "github.com/photoprism/photoprism/pkg/i18n"
"github.com/photoprism/photoprism/pkg/log/status"
) )
// BatchPhotosEdit returns and updates the metadata of multiple photos. // BatchPhotosEdit returns and updates the metadata of multiple photos.
@@ -76,8 +78,8 @@ func BatchPhotosEdit(router *gin.RouterGroup) {
var preloadedPhotos map[string]*entity.Photo var preloadedPhotos map[string]*entity.Photo
if hydrated, err := query.PhotoPreloadByUIDs(photos.UIDs()); err != nil { if hydrated, preloadErr := query.PhotoPreloadByUIDs(photos.UIDs()); preloadErr != nil {
log.Errorf("batch: failed to preload photo selection: %s", err) log.Errorf("batch: %s (preload selection)", preloadErr)
AbortUnexpectedError(c) AbortUnexpectedError(c)
return return
} else { } else {
@@ -95,11 +97,12 @@ func BatchPhotosEdit(router *gin.RouterGroup) {
switch { switch {
case errors.Is(saveErr, batch.ErrBatchEditBusy), errors.Is(saveErr, batch.ErrBatchEditCanceled): case errors.Is(saveErr, batch.ErrBatchEditBusy), errors.Is(saveErr, batch.ErrBatchEditCanceled):
log.Warnf("batch: %s", saveErr) log.Warnf("batch: %s (save)", saveErr)
AbortBusy(c) AbortBusy(c)
return return
case saveErr != nil: case saveErr != nil:
log.Errorf("batch: failed to persist photo updates: %s", saveErr) log.Errorf("batch: %s (save)", saveErr)
event.AuditErr([]string{ClientIP(c), "session %s", "batch edit", status.Error(saveErr)}, s.RefID)
AbortUnexpectedError(c) AbortUnexpectedError(c)
return return
} }
@@ -108,13 +111,18 @@ func BatchPhotosEdit(router *gin.RouterGroup) {
saveResults = outcome.Results saveResults = outcome.Results
preloadedPhotos = outcome.Preloaded preloadedPhotos = outcome.Preloaded
savedAny = outcome.SavedAny savedAny = outcome.SavedAny
if n := len(saveRequests); n > 0 && (savedAny || outcome.Stats.AlbumMutations > 0 || outcome.Stats.LabelMutations > 0) {
event.AuditInfo([]string{ClientIP(c), "session %s", "batch edit", "update %s", status.Succeeded},
s.RefID, english.Plural(n, "picture", "pictures"))
}
} }
// Refresh selected photos from database? // Refresh selection if core metadata changed; albums and labels are automatically refreshed.
if !savedAny { if savedAny {
// Don't refresh. if photos, _, err = search.BatchPhotos(frm.Photos, s); err != nil {
} else if photos, _, err = search.BatchPhotos(frm.Photos, s); err != nil { log.Errorf("batch: %s (refresh selection)", clean.Error(err))
log.Errorf("batch: %s (refresh selection)", clean.Error(err)) }
} }
// Create batch edit form values form from photo metadata using the refreshed entities so // Create batch edit form values form from photo metadata using the refreshed entities so