@@ -330,7 +330,9 @@ async def probe_credential(credential_id: str,
330330 quota = await provider .probe_quota (data )
331331 except Exception as error : # noqa: BLE001 - 探测失败 → unknown,不当作 0
332332 credentials .mark_probe_failed (credential_id )
333- return {"probed" : False , "reason" : type (error ).__name__ }
333+ reason = describe_probe_failure (error )
334+ logger .info ("额度探测失败 %s: %s" , credential_id , reason )
335+ return {"probed" : False , "reason" : reason , "detail" : str (error )[:200 ]}
334336 credentials .save_quota (credential_id , quota )
335337 return {"probed" : True , "remaining" : quota .remaining , "total" : quota .total ,
336338 "cycle_end" : quota .cycle_end }
@@ -481,6 +483,36 @@ def resolve_public_callback_url(settings: Settings) -> str:
481483 return settings .public_base_url .rstrip ("/" ) + "/authorize"
482484
483485
486+ def describe_probe_failure (error : Exception ) -> str :
487+ """把探测异常翻译成用户能据以行动的原因。
488+
489+ 不能直接暴露 Python 类名(如 UpstreamProtocolViolation)——那是实现细节,
490+ 用户看到它既判断不出问题,也不知道下一步该做什么。
491+ """
492+ from .provider .codebuddy .client import UpstreamHTTPError as CodeBuddyHTTPError
493+ from .provider .codebuddy .events import (
494+ UpstreamProtocolViolation as CodeBuddyViolation ,
495+ )
496+ from .provider .trae .client import UpstreamHTTPError as TraeHTTPError
497+ from .provider .trae .events import UpstreamProtocolViolation as TraeViolation
498+
499+ http_errors = (CodeBuddyHTTPError , TraeHTTPError )
500+ if isinstance (error , http_errors ):
501+ status = getattr (error , "status" , 0 )
502+ if status in (401 , 403 ):
503+ return "credential_rejected" # 凭证失效,需要重新登录
504+ if status == 429 :
505+ return "rate_limited" # 上游限流,稍后再试
506+ if status >= 500 :
507+ return "upstream_unavailable" # 上游故障,与凭证无关
508+ return "upstream_rejected" # 上游拒绝该请求
509+ if isinstance (error , (CodeBuddyViolation , TraeViolation )):
510+ return "upstream_response_invalid" # 响应结构不符,可能是上游改版
511+ if isinstance (error , TimeoutError ):
512+ return "upstream_timeout"
513+ return "unknown_error"
514+
515+
484516def _upstream_auth (registry : dict , settings : Settings ) -> dict :
485517 """返回支持 poll 轨道的 provider 的 OAuth 实现(当前仅 CodeBuddy)。"""
486518 flows : dict = {}
0 commit comments