{"record":{"id":"cc4941cfe57ed295","repo":"ATH-MaaS/Pixelle-Video","slug":"http-resp-status-code","errorCode":null,"errorMessage":"视频下载失败: HTTP {resp.status_code}","messagePattern":"视频下载失败: HTTP (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"pixelle_video/services/api_services/video_dashscope.py","lineNumber":415,"sourceCode":"        logger.info(f\"DashscopeVideoClient: 视频生成成功: {video_url}\")\n\n        # 确保输出目录存在\n        os.makedirs(os.path.dirname(save_path), exist_ok=True)\n\n        # 下载视频\n        resp = self._with_network_retry(\n            \"download video\",\n            lambda: requests.get(\n                video_url,\n                stream=True,\n                timeout=120,\n                proxies={\"http\": self.local_proxy, \"https\": self.local_proxy} if self.local_proxy else None,\n            ),\n            max_attempts=5,\n            base_delay=3.0,\n        )\n        if resp.status_code != 200:\n            raise RuntimeError(f\"视频下载失败: HTTP {resp.status_code}\")\n\n        with open(save_path, 'wb') as f:\n            for chunk in resp.iter_content(chunk_size=8192):\n                if chunk:\n                    f.write(chunk)\n\n        logger.info(f\"DashscopeVideoClient: 视频已保存: {save_path}\")\n        return video_url\n\n    def _is_video_edit_model(self, model: str) -> bool:\n        \"\"\"Return True for DashScope video-edit model IDs.\"\"\"\n        model_lower = model.lower()\n        return \"videoedit\" in model_lower or \"video-edit\" in model_lower\n\n    def _is_reference_to_video_model(self, model: str) -> bool:\n        \"\"\"Return True for DashScope reference-to-video model IDs.\"\"\"\n        return \"r2v\" in model.lower()\n","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/ATH-MaaS/Pixelle-Video/blob/848b054e4fae40dabc62ec58e960b573e83793ac/pixelle_video/services/api_services/video_dashscope.py#L397-L433","documentation":"After DashScope returns a video URL, generate_video downloads it with requests.get (wrapped in network retry). If the final HTTP response status is not 200 — even after up to 5 retry attempts with 3s base delay — the client raises RuntimeError '视频下载失败: HTTP <status>'.","triggerScenarios":"requests.get(video_url, stream=True, timeout=120) returns a non-200 status after _with_network_retry exhausts max_attempts=5; typically 403 (expired/protected CDN URL), 404 (deleted object), or 5xx from the Aliyun OSS/CDN host (video_dashscope.py:403-415).","commonSituations":"Waiting too long between generation and download so the signed URL expires (DashScope video URLs are time-limited), corporate proxy misconfiguring self.local_proxy, CDN transient outage during retries, or the generated object being cleaned up server-side.","solutions":["Download the video promptly after generation; signed OSS URLs expire, so re-run generation if the URL is old.","Check the status code: 403/404 means the URL is expired or invalid — regenerate; 5xx means transient — retry later.","Verify self.local_proxy is correct or None; a bad proxy often yields 403/407 from the CDN.","Increase max_attempts/base_delay in _with_network_retry for the download call if CDN flakiness is common in your region."],"exampleFix":"# before\nif resp.status_code != 200:\n    raise RuntimeError(f\"视频下载失败: HTTP {resp.status_code}\")\n# after\nif resp.status_code != 200:\n    if resp.status_code in (403, 404):\n        raise RuntimeError(\n            f\"视频下载失败: HTTP {resp.status_code} (URL 可能已过期，请重新生成)\"\n        )\n    raise RuntimeError(f\"视频下载失败: HTTP {resp.status_code}\")","handlingStrategy":"retry","validationCode":"import requests\ndef url_alive(video_url: str, proxy: str | None = None) -> bool:\n    try:\n        r = requests.head(video_url, timeout=10, allow_redirects=True,\n                          proxies={\"http\": proxy, \"https\": proxy} if proxy else None)\n        return r.status_code == 200\n    except requests.RequestException:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    url = client.generate_video(...)\nexcept RuntimeError as e:\n    if \"视频下载失败\" in str(e):\n        status = int(str(e).rsplit(\"HTTP \", 1)[-1])\n        if status in (403, 404):\n            url = client.generate_video(...)  # URL 过期/失效，重新生成\n        else:\n            time.sleep(5); url = client.generate_video(...)  # 5xx 稍后重试","preventionTips":["Download immediately after generation — signed OSS URLs expire","Verify proxy settings (self.local_proxy) point to a working egress","Prefer HEAD-checking the URL before streaming the full download","Run downloads on a network with reliable access to Aliyun OSS/CDN"],"tags":["http","download","network","dashscope"],"backgroundTag":"http-download-failed","analyzedSha":"848b054e4fae40dabc62ec58e960b573e83793ac","analyzedAt":"2026-08-30T03:24:41.468Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}