diff --git a/video-gen-api/app/services/private_portrait/ark_client.py b/video-gen-api/app/services/private_portrait/ark_client.py index c2078a1d..8b6b3a35 100644 --- a/video-gen-api/app/services/private_portrait/ark_client.py +++ b/video-gen-api/app/services/private_portrait/ark_client.py @@ -4,6 +4,8 @@ import asyncio import json from typing import Any +from fastapi import HTTPException + from app.config import settings from app.enums.private_portrait import ( ARK_PRIVATE_PORTRAIT_HOST, @@ -135,10 +137,10 @@ class ArkPrivateAssetClient: credentials, 10, 60, + "https", ) # volcengine SDK 的 ApiInfo.query 必须是 dict,不能传 "Action=xxx&Version=xxx" 字符串。 - # 否则 Service.merge() 会按 dict 下标读取字符串,触发: - # TypeError: string indices must be integers, not 'str'。 + # ServiceInfo 默认 scheme='http',这里必须显式传 https,避免请求走 http://host:80。 api_info = { action.value: ApiInfo( "POST", @@ -153,7 +155,13 @@ class ArkPrivateAssetClient: # volcengine SDK 在签名阶段会对 request.body 做 hashlib.sha256(body)。 # Python 3 下 hashlib.sha256 只能接收 bytes/bytearray,不能接收 dict 或 str。 body = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8") - raw = service.json(action.value, {}, body) + try: + raw = service.json(action.value, {}, body) + except Exception as exc: + message = self._exception_message(exc) + if "ConnectTimeout" in message or "timed out" in message or "Connection" in message: + raise HTTPException(status_code=502, detail=f"火山私域素材接口连接失败:{message}") from exc + raise ArkPrivateAssetClientError(f"{action.value} 请求火山私域素材接口异常:{message}") from exc resp = self._normalize_response(raw) metadata = resp.get("ResponseMetadata") if isinstance(resp, dict) else None @@ -174,6 +182,15 @@ class ArkPrivateAssetClient: return resp return {"raw": resp, "RequestId": request_id} + @staticmethod + def _exception_message(exc: Exception) -> str: + if exc.args: + raw = exc.args[0] + if isinstance(raw, (bytes, bytearray)): + return raw.decode("utf-8", errors="ignore") + return str(raw) + return str(exc) + @staticmethod def _normalize_response(raw: Any) -> dict[str, Any]: if raw is None: