diff --git a/services/anthropic_service.py b/services/anthropic_service.py index a3f13cf..3f70b44 100644 --- a/services/anthropic_service.py +++ b/services/anthropic_service.py @@ -100,7 +100,7 @@ class AnthropicService: logger.info("[Anthropic] is_available()=False — cost throttled, caller 應 fallback Gemini") return False except Exception: - pass # cost_throttle 不可用不阻擋 + logger.warning("[Anthropic] cost_throttle check failed; continuing as available", exc_info=True) return True def generate( diff --git a/tests/test_anthropic_service.py b/tests/test_anthropic_service.py index c705d1b..df152bf 100644 --- a/tests/test_anthropic_service.py +++ b/tests/test_anthropic_service.py @@ -18,6 +18,7 @@ from __future__ import annotations import os import sys +import logging from types import SimpleNamespace from unittest.mock import MagicMock, patch @@ -82,6 +83,27 @@ def test_is_available_true_when_sdk_ready(mock_sdk): assert svc.is_available() is True +def test_is_available_logs_cost_throttle_failure(mock_sdk, monkeypatch, caplog): + """cost_throttle 檢查故障時仍維持 Claude 可用,但必須留下診斷 log。""" + from services.anthropic_service import AnthropicService + import services.cost_throttle_service as cost_throttle_service + + def _raise_cost_throttle_error(provider): + raise RuntimeError("cost throttle unavailable") + + monkeypatch.setattr( + cost_throttle_service, + "is_provider_throttled", + _raise_cost_throttle_error, + ) + caplog.set_level(logging.WARNING, logger="services.anthropic_service") + + svc = AnthropicService(api_key='sk-ant-test') + + assert svc.is_available() is True + assert "cost_throttle check failed" in caplog.text + + def test_is_available_false_on_import_error(monkeypatch): """SDK 未安裝(ImportError)→ is_available() False,不 raise""" # 移除 anthropic 模組讓 import 失敗