feat(downloads): categorize download failures + a readable error dialog (S2)
Failed downloads stored the raw yt-dlp/ffmpeg text and dumped it as a truncated red one-liner in the queue. Classify the failure into a category (unavailable / login_required / geo_blocked / format_unavailable / drm / postprocess / source_missing / network / unknown) and surface it properly: - backend: app/downloads/errors.classify maps the raw message to a category code; the worker stores it in the new download_jobs.error_code (migration 0061) at both failure sites; resume clears it; the serializer exposes it. Raw text kept as technical detail. - frontend: the queue row shows a clean localized reason + a "details" link opening a modal with the explanation, the raw text behind a disclosure, and a Retry only for transient categories (network/postprocess/unknown). - tests: classify() unit coverage over verbatim yt-dlp/ffmpeg message shapes.
This commit is contained in:
@@ -31,6 +31,7 @@ from app import sysconfig
|
||||
from app.config import settings
|
||||
from app.db import SessionLocal
|
||||
from app.downloads import edit as editmod
|
||||
from app.downloads import errors as dlerrors
|
||||
from app.downloads import formats, quota, service, storage
|
||||
from app.models import DownloadJob, MediaAsset
|
||||
from app.titles import normalize_title
|
||||
@@ -654,6 +655,7 @@ def _download(job_id: int, asset_id: int, source_kind: str, source_ref: str, spe
|
||||
if job:
|
||||
job.status = "error"
|
||||
job.error = msg
|
||||
job.error_code = dlerrors.classify(msg)
|
||||
job.phase = None
|
||||
db.commit()
|
||||
log.warning("job %s failed: %s", job_id, msg)
|
||||
@@ -685,6 +687,7 @@ def _fail_edit(job_id: int, asset_id: int, msg: str) -> None:
|
||||
if job:
|
||||
job.status = "error"
|
||||
job.error = msg
|
||||
job.error_code = dlerrors.classify(msg)
|
||||
job.phase = None
|
||||
db.commit()
|
||||
log.warning("edit job %s failed: %s", job_id, msg)
|
||||
|
||||
Reference in New Issue
Block a user