Add orphaned job prevention in generate_book_task
- Guard checks at task start verify: run exists in DB, project folder exists, bible.json exists and is parseable, and bible has at least one book - Any failed check marks the run as 'failed' and returns early, preventing jobs from writing to the wrong book or orphaned project directories Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
50
web/tasks.py
50
web/tasks.py
@@ -107,6 +107,56 @@ def generate_book_task(run_id, project_path, bible_path, allow_copy=True, feedba
|
||||
|
||||
_task_log(f"Task picked up by Huey worker. project_path={project_path}")
|
||||
|
||||
# 0. Orphaned Job Guard — verify that all required resources exist before
|
||||
# doing any work. If a run, project folder, or bible is missing, terminate
|
||||
# silently and mark the run as failed to prevent data being written to the
|
||||
# wrong book or project.
|
||||
db_path_early = os.path.join(config.DATA_DIR, "bookapp.db")
|
||||
|
||||
try:
|
||||
with sqlite3.connect(db_path_early, timeout=10) as _conn:
|
||||
_row = _conn.execute("SELECT id FROM run WHERE id = ?", (run_id,)).fetchone()
|
||||
if not _row:
|
||||
_task_log(f"ABORT: Run #{run_id} no longer exists in DB. Terminating silently.")
|
||||
return
|
||||
except Exception as _e:
|
||||
_task_log(f"WARNING: Could not verify run #{run_id} existence: {_e}")
|
||||
|
||||
if not os.path.isdir(project_path):
|
||||
_task_log(f"ABORT: Project folder missing ({project_path}). Marking run #{run_id} as failed.")
|
||||
try:
|
||||
_robust_update_run_status(db_path_early, run_id, 'failed',
|
||||
end_time=datetime.utcnow().isoformat())
|
||||
except Exception: pass
|
||||
return
|
||||
|
||||
if not os.path.isfile(bible_path):
|
||||
_task_log(f"ABORT: Bible file missing ({bible_path}). Marking run #{run_id} as failed.")
|
||||
try:
|
||||
_robust_update_run_status(db_path_early, run_id, 'failed',
|
||||
end_time=datetime.utcnow().isoformat())
|
||||
except Exception: pass
|
||||
return
|
||||
|
||||
# Validate that the bible has at least one book entry
|
||||
try:
|
||||
with open(bible_path, 'r', encoding='utf-8') as _bf:
|
||||
_bible_check = json.load(_bf)
|
||||
if not _bible_check.get('books'):
|
||||
_task_log(f"ABORT: Bible has no books defined. Marking run #{run_id} as failed.")
|
||||
try:
|
||||
_robust_update_run_status(db_path_early, run_id, 'failed',
|
||||
end_time=datetime.utcnow().isoformat())
|
||||
except Exception: pass
|
||||
return
|
||||
except Exception as _e:
|
||||
_task_log(f"ABORT: Could not parse bible ({bible_path}): {_e}. Marking run #{run_id} as failed.")
|
||||
try:
|
||||
_robust_update_run_status(db_path_early, run_id, 'failed',
|
||||
end_time=datetime.utcnow().isoformat())
|
||||
except Exception: pass
|
||||
return
|
||||
|
||||
# 1. Setup Logging
|
||||
log_filename = f"system_log_{run_id}.txt"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user