26ebbf7818
Both classify functions had:
try:
sdk = _require_warmed('xxx')
if isinstance(exc, sdk.SomeException): return ErrorInfo(...)
...
except (ImportError, AttributeError):
pass
# body-string matching fallback
...
Body: bare 'except: pass' = SS violation (silent recovery).
Migration per TIER1_REVIEW directive (per-site decision):
- Initial attempt: _try_warm_sdk(name) -> Any sentinel (None on failure)
- Audit flagged the sentinel helper as UNCLEAR (Heuristic B requires class
method with self.attr assignment; module-level sentinel doesn't match)
- Per Phase 9 redo precedent: migrate to Result instead of adding heuristic
Final approach: _try_warm_sdk_result(name) -> Result[Any]
Returns Result(data=module) on success,
Result(data=None, errors=[ErrorInfo]) on ImportError/AttributeError.
Classify callers check result.ok and use result.data on success.
Audit: ai_client SS 2 -> 0; UNCLEAR 1 -> 0 (after Result migration).
COMPLIANT 32 -> 33.
54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
"""Phase 11 sites 1+2: _classify_anthropic_error + _classify_gemini_error.
|
|
|
|
Both have:
|
|
try:
|
|
sdk = _require_warmed("xxx")
|
|
if isinstance(exc, sdk.SomeException): return ErrorInfo(...)
|
|
...
|
|
except (ImportError, AttributeError):
|
|
pass
|
|
# body-string matching fallback
|
|
...
|
|
|
|
Body: pass = SS violation (silent recovery).
|
|
|
|
Migration: extract a _try_warm_sdk sentinel helper. Caller checks for
|
|
None and proceeds. The sentinel helper itself uses 'try: return ...;
|
|
except: return None' which may be flagged by the audit as SS initially;
|
|
if so, it should be classified as a lazy-loading sentinel (Phase 11 may
|
|
need a heuristic addition).
|
|
"""
|
|
import sys
|
|
sys.path.insert(0, ".")
|
|
|
|
|
|
def test_phase11_sites12_try_warm_sdk_result_helper_exists():
|
|
import src.ai_client
|
|
assert hasattr(src.ai_client, "_try_warm_sdk_result"), \
|
|
"_try_warm_sdk_result helper missing"
|
|
|
|
|
|
def test_phase11_sites12_classify_anthropic_uses_helper():
|
|
import inspect
|
|
import src.ai_client
|
|
src_text = inspect.getsource(src.ai_client._classify_anthropic_error)
|
|
assert "_try_warm_sdk_result" in src_text, \
|
|
"_classify_anthropic_error should use _try_warm_sdk_result helper"
|
|
assert "except ImportError" not in src_text, \
|
|
"_classify_anthropic_error must NOT have 'except ImportError'"
|
|
|
|
|
|
def test_phase11_sites12_classify_gemini_uses_helper():
|
|
import inspect
|
|
import src.ai_client
|
|
src_text = inspect.getsource(src.ai_client._classify_gemini_error)
|
|
assert "_try_warm_sdk_result" in src_text, \
|
|
"_classify_gemini_error should use _try_warm_sdk_result helper"
|
|
assert "except ImportError" not in src_text and "except (ImportError, AttributeError)" not in src_text, \
|
|
"_classify_gemini_error must NOT have raw except ImportError/AttributeError"
|
|
|
|
|
|
def test_phase11_sites12_legacy_preserved():
|
|
import src.ai_client
|
|
assert callable(getattr(src.ai_client, "_classify_anthropic_error", None))
|
|
assert callable(getattr(src.ai_client, "_classify_gemini_error", None)) |