fix(collection): correct run status during jobs and add retry-failed

Fix pending mislabeled as fail due to timezone and queue stale checks, show full error details, sync live progress counts, and add retry-failed endpoint for failed NEs only.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-28 10:05:20 +08:00
parent 3024e13812
commit 3413d5bf32
10 changed files with 202 additions and 40 deletions

View file

@ -2,6 +2,7 @@ from __future__ import annotations
import logging
import re
import traceback
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeout
from datetime import datetime
from pathlib import Path
@ -9,7 +10,7 @@ from typing import Any
from netmiko import ConnectHandler
from .collection_job_state import finalize_collection_job
from .collection_job_state import finalize_collection_job, sync_job_progress
from .config import settings
from .db import SessionLocal
from .models import ManagedNE, NeCollectionJob, NeCollectionRun
@ -30,6 +31,13 @@ def _executor_pool() -> ThreadPoolExecutor:
return _executor
def _format_run_error(exc: BaseException) -> str:
head = f"{type(exc).__name__}: {exc}"
tb = traceback.format_exc().strip()
text = f"{head}\n{tb}" if tb else head
return text[:1020]
def _safe_filename_part(text: str) -> str:
s = re.sub(r'[<>:"/\\|?*]', "_", str(text or "").strip())
return s[:80] or "device"
@ -152,14 +160,15 @@ def _run_single(job_id: str, run_id: str, commands: list[str]) -> None:
ended_at=finished_at,
)
except CredentialCryptoError as exc:
_update_run(run_id, status="fail", message=str(exc)[:1000], ended_at=datetime.now())
_update_run(run_id, status="fail", message=str(exc)[:1020], ended_at=datetime.now())
except Exception as exc:
_log.exception("collection failed run=%s", run_id)
_update_run(run_id, status="fail", message=str(exc).split("\n")[0][:1000], ended_at=datetime.now())
_update_run(run_id, status="fail", message=_format_run_error(exc), ended_at=datetime.now())
finally:
db.close()
db2 = SessionLocal()
try:
sync_job_progress(db2, job_id)
finalize_collection_job(db2, job_id)
finally:
db2.close()