From 52fe911bcc4216b557a2a6192cb8abd67cac5cc2 Mon Sep 17 00:00:00 2001 From: Daan Meijer Date: Thu, 8 Oct 2026 11:28:32 +0200 Subject: [PATCH] Garbage: a probe whose release another probe deleted is not an error Two probes of one release can be applied at once; when one deletes the release as garbage, the other's inserts (e.g. a par2 listing) violated the foreign key and the node got a 500. Co-Authored-By: Claude Opus 5.5 --- app/services/ContentService.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/services/ContentService.ts b/app/services/ContentService.ts index 8aeed7d..5c09944 100644 --- a/app/services/ContentService.ts +++ b/app/services/ContentService.ts @@ -158,7 +158,17 @@ class ContentService { * what it found. Then the release is deleted if it turned out to be garbage (D42). */ async apply(task: InspectTask, probe: InspectProbe): Promise { - const result = await this.applyProbe(task, probe) + let result: ContentResult + try { + result = await this.applyProbe(task, probe) + } catch (error: any) { + // Another probe of the release (its first volume, its par2) deleted it as garbage meanwhile: + // what this one found has nowhere to go (LOG.md 2026-10-08 (7)). + if (error.code === '23503' && !(await db.from('files').where('id', task.fileId).select('id').first())) { + return { named: 0, contentType: probe.contentType, garbage: 'deleted meanwhile' } + } + throw error + } result.garbage = (await GarbageFilter.afterProbe(task.fileId, probe.contentType)) ?? undefined return result } @@ -291,7 +301,7 @@ export function describeContent(filename: string, content: ContentResult | null) if (content?.contentType === 'nzbe') lines.push(`"${filename}" is an encrypted NZB container.`) if (content?.contentType === 'rclone') lines.push(`"${filename}" is rclone-encrypted.`) if (content?.yencName) lines.push(`"${filename}" is "${content.yencName}" (yEnc name).`) - if (content?.garbage) lines.push(`"${filename}": release deleted as garbage (${content.garbage}, no name or password).`) + if (content?.garbage) lines.push(`"${filename}": release deleted as garbage (${content.garbage === 'deleted meanwhile' ? 'by another probe' : `${content.garbage}, no name or password`}).`) if (content?.nicovideo) lines.push(`"${filename}" → "${content.nicovideo}".`) if (content?.sfvMoved) lines.push(`SFV "${filename}" moved ${content.sfvMoved} files into its release.`) if (content?.contentType === 'yencbin') lines.push(`"${filename}" is a yEncBin encrypted container.`)