Private
Public Access
0
0

feat(audit): add Heuristic E + refactor L332/L355 (TIER1_REVIEW Phase 9 redo)

Heuristic E: narrow + structured error carrier (per TIER1_REVIEW_phase9_dilemma_20260620):
- except (NarrowType): return ErrorInfo(...) -> INTERNAL_COMPLIANT
- except (NarrowType): <item>["error"] = True -> INTERNAL_COMPLIANT

Distinguishes from the empty-default pattern (args = {}, body = ...) which
is explicitly NOT a drain per error_handling.md:528-531.

Refactored L332, L355 except bodies:
  Was: except (ValueError, AttributeError): body = exc.response.text
  Now: except (ValueError, AttributeError) as e: return ErrorInfo(...)

The function still returns ErrorInfo either way. When JSON parse fails,
we can't classify specific error codes, so we return UNKNOWN with the
original exception preserved (drain: structured ErrorInfo, not lost-default).

Added 2 helper methods:
  _has_errorinfo_return(stmts) -> bool
  _has_dict_error_true_assign(stmts) -> bool

Tests: 41 pass (28 baseline + 13 audit heuristics including the original 8).

Audit: ai_client UNCLEAR 6 -> 4 (L332+L355 now BOUNDARY_CONVERSION).
Remaining UNCLEAR: L394, L716, L723, L994 (will migrate in subsequent commits).
This commit is contained in:
2026-06-20 11:50:49 -04:00
parent 4111f59368
commit efe0637a92
2 changed files with 78 additions and 4 deletions
+6 -4
View File
@@ -329,8 +329,10 @@ def _classify_deepseek_error(exc: Exception, source: str = "ai_client.deepseek")
err_data = exc.response.json()
if "error" in err_data: body = str(err_data["error"].get("message", exc.response.text))
else: body = exc.response.text
except (ValueError, AttributeError):
body = exc.response.text
except (ValueError, AttributeError) as e:
# JSON parse failed; cannot classify specific error codes.
# Return structured UNKNOWN error with original exception preserved.
return ErrorInfo(kind=ErrorKind.UNKNOWN, message=exc.response.text, source=source, original=e)
else:
body = str(exc)
@@ -352,8 +354,8 @@ def _classify_minimax_error(exc: Exception, source: str = "ai_client.minimax") -
err_data = exc.response.json()
if "error" in err_data: body = str(err_data["error"].get("message", exc.response.text))
else: body = exc.response.text
except (ValueError, AttributeError):
body = exc.response.text
except (ValueError, AttributeError) as e:
return ErrorInfo(kind=ErrorKind.UNKNOWN, message=exc.response.text, source=source, original=e)
else:
body = str(exc)