From 80ae7ea1ff61571dac2ae25d66ee911eee9f717b Mon Sep 17 00:00:00 2001 From: Amadeus Mader Date: Sat, 7 Mar 2026 18:52:19 +0100 Subject: [PATCH] fix(oban): handle orphaned source deletion jobs gracefully Add rescue block to SourceDeletionWorker to handle cases where the source no longer exists. This prevents infinite retries when a deletion job fails and the source has already been removed from the database. --- Pinchflat_improvements.md | 2 +- lib/pinchflat/sources/source_deletion_worker.ex | 3 +++ test/pinchflat/sources/source_deletion_worker_test.exs | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Pinchflat_improvements.md b/Pinchflat_improvements.md index a8a5488..61d3b90 100644 --- a/Pinchflat_improvements.md +++ b/Pinchflat_improvements.md @@ -129,7 +129,7 @@ sqlite3 /path/to/pinchflat.db " docker compose start pinchflat ``` -## Issue 5: Orphaned deletion jobs for non-existent sources +## Issue 5: Orphaned deletion jobs for non-existent sources [COMPLETED] **Problem:** When a source is deleted, a `SourceDeletionWorker` job is created. If this job fails repeatedly (e.g., due to database busy errors or files already deleted), it keeps retrying indefinitely even after the source no longer exists. diff --git a/lib/pinchflat/sources/source_deletion_worker.ex b/lib/pinchflat/sources/source_deletion_worker.ex index 9c36837..689f3a5 100644 --- a/lib/pinchflat/sources/source_deletion_worker.ex +++ b/lib/pinchflat/sources/source_deletion_worker.ex @@ -34,5 +34,8 @@ defmodule Pinchflat.Sources.SourceDeletionWorker do source = Sources.get_source!(source_id) Sources.delete_source(source, delete_files: delete_files) + rescue + Ecto.NoResultsError -> Logger.info("#{__MODULE__} discarded: source #{source_id} not found") + Ecto.StaleEntryError -> Logger.info("#{__MODULE__} discarded: source #{source_id} stale") end end diff --git a/test/pinchflat/sources/source_deletion_worker_test.exs b/test/pinchflat/sources/source_deletion_worker_test.exs index fe2ec3d..ff02c3a 100644 --- a/test/pinchflat/sources/source_deletion_worker_test.exs +++ b/test/pinchflat/sources/source_deletion_worker_test.exs @@ -48,5 +48,9 @@ defmodule Pinchflat.Sources.SourceDeletionWorkerTest do assert_raise Ecto.NoResultsError, fn -> Repo.reload!(media_item) end refute File.exists?(media_item.media_filepath) end + + test "does not blow up if the record doesn't exist" do + assert :ok = perform_job(SourceDeletionWorker, %{id: 0}) + end end end