fix: gate retries by error category with backoff

Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
Jim Lancaster
2026-08-23 18:30:54 -05:00
co-authored by Copilot App
parent f193b2800b
commit 86cdb4035c
7 changed files with 112 additions and 2 deletions
@@ -2,6 +2,8 @@
import asyncio
import time
from datetime import UTC
from datetime import datetime
from pathlib import Path
from uuid import uuid4
@@ -20,6 +22,7 @@ from transcription.db.models import Source
from transcription.providers.base import TranscriptionResult
from transcription.services import ServiceBundle
from transcription.services import workflows as workflows_module
from transcription.services.workflows import advance_job
from transcription.services.workflows import process_queued_job
@@ -366,3 +369,63 @@ class TestWorkflowReliability:
result = await task
assert result is not None
assert result.status == JobStatus.TRANSCRIBED
@pytest.mark.asyncio
async def test_failed_job_with_validation_category_is_not_requeued(self, default_session_factory):
services = ServiceBundle.from_session_factory(default_session_factory)
async with services.jobs._session_scope() as session:
document = Document(id=uuid4(), name="validation-failure-doc")
session.add(document)
await session.flush()
source = Source(
document_id=document.id,
page_number=1,
upload_name="validation.jpg",
filename="validation.jpg",
file_path=str(Path("tests/fixtures/images/real/Book Two - page 02.jpg")),
file_hash="9" * 64,
file_size_bytes=1,
)
session.add(source)
await session.flush()
job = Job(document_id=document.id, status=JobStatus.FAILED, retry_count=0)
session.add(job)
await session.flush()
job_source = JobSource(job_id=job.id, source_id=source.id, status=JobSourceStatus.FAILED)
session.add(job_source)
await session.flush()
now = datetime.now(UTC)
session.add(
ExecutionAttempt(
job_source_id=job_source.id,
job_id=job.id,
source_id=source.id,
attempt_number=1,
status=JobSourceStatus.FAILED,
provider="fixture",
started_at=now,
finished_at=now,
duration_ms=0,
error_category="validation_error",
error_detail="invalid payload",
)
)
await session.commit()
failed_job = await services.jobs.read_job(job_id=job.id, session=session)
result = await advance_job(
failed_job,
services=services,
settings=Settings(openrouter_api_key="test-key", worker_max_retries=1),
)
assert result is None
async with services.jobs._session_scope() as session:
persisted = await session.get(Job, failed_job.id)
assert persisted is not None
assert persisted.status == JobStatus.FAILED
assert persisted.retry_count == 0