From 832b7fbff434adf991df333db4e982497e6c7b02 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Sun, 8 Mar 2026 07:37:38 -0700 Subject: [PATCH] fix: better error messages when there's another instance of Pocket ID running (#1370) --- backend/internal/bootstrap/bootstrap.go | 6 +++++- backend/internal/cmds/import.go | 9 ++++----- backend/internal/service/app_lock_service.go | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/internal/bootstrap/bootstrap.go b/backend/internal/bootstrap/bootstrap.go index 2b033684..692e6b0b 100644 --- a/backend/internal/bootstrap/bootstrap.go +++ b/backend/internal/bootstrap/bootstrap.go @@ -2,6 +2,7 @@ package bootstrap import ( "context" + "errors" "fmt" "log/slog" "time" @@ -11,6 +12,7 @@ import ( "github.com/pocket-id/pocket-id/backend/internal/common" "github.com/pocket-id/pocket-id/backend/internal/job" + "github.com/pocket-id/pocket-id/backend/internal/service" "github.com/pocket-id/pocket-id/backend/internal/storage" "github.com/pocket-id/pocket-id/backend/internal/utils" ) @@ -60,7 +62,9 @@ func Bootstrap(ctx context.Context) error { } waitUntil, err := svc.appLockService.Acquire(ctx, false) - if err != nil { + if errors.Is(err, service.ErrLockUnavailable) { + return errors.New("it appears that there's already one instance of Pocket ID running; running multiple replicas of Pocket ID is currently not supported") + } else if err != nil { return fmt.Errorf("failed to acquire application lock: %w", err) } diff --git a/backend/internal/cmds/import.go b/backend/internal/cmds/import.go index 974d049e..0f51c492 100644 --- a/backend/internal/cmds/import.go +++ b/backend/internal/cmds/import.go @@ -119,11 +119,10 @@ func acquireImportLock(ctx context.Context, db *gorm.DB, force bool) error { defer cancel() waitUntil, err := appLockService.Acquire(opCtx, force) - if err != nil { - if errors.Is(err, service.ErrLockUnavailable) { - //nolint:staticcheck - return errors.New("Pocket ID must be stopped before importing data; please stop the running instance or run with --forcefully-acquire-lock to terminate the other instance") - } + if errors.Is(err, service.ErrLockUnavailable) { + //nolint:staticcheck + return errors.New("Pocket ID must be stopped before importing data; please stop the running instance or run with --forcefully-acquire-lock to terminate the other instance") + } else if err != nil { return fmt.Errorf("failed to acquire application lock: %w", err) } diff --git a/backend/internal/service/app_lock_service.go b/backend/internal/service/app_lock_service.go index 0a309b15..f1bd0c2a 100644 --- a/backend/internal/service/app_lock_service.go +++ b/backend/internal/service/app_lock_service.go @@ -96,7 +96,8 @@ func (s *AppLockService) Acquire(ctx context.Context, force bool) (waitUntil tim var prevLock lockValue if prevLockRaw != "" { - if err := prevLock.Unmarshal(prevLockRaw); err != nil { + err = prevLock.Unmarshal(prevLockRaw) + if err != nil { return time.Time{}, fmt.Errorf("decode existing lock value: %w", err) } } @@ -142,7 +143,8 @@ func (s *AppLockService) Acquire(ctx context.Context, force bool) (waitUntil tim return time.Time{}, fmt.Errorf("lock acquisition failed: %w", res.Error) } - if err := tx.Commit().Error; err != nil { + err = tx.Commit().Error + if err != nil { return time.Time{}, fmt.Errorf("commit lock acquisition: %w", err) }