Files
Devour/.desloppify/subagents/runs/20260224_101201/results/batch-5.raw.txt
T
2026-02-24 12:10:13 +01:00

113 lines
6.3 KiB
Plaintext

{
"batch": "Cross-cutting Sweep",
"batch_index": 5,
"assessments": {
"error_consistency": 68.0
},
"dimension_notes": {
"error_consistency": {
"evidence": [
"RPC paths mix strict and lax decode behavior: `cmd/serve.go` returns decode errors for `devour_scrape`/`devour_ask` but ignores decode errors for `devour_query` and `devour_sync` (`_ = json.Unmarshal(...)`).",
"`cmd/serve.go` `devour_status` ignores errors from `LoadSourceState` and `EnsureIndexed` then dereferences `idxStats.Documents`, which can panic on nil when indexing fails.",
"`internal/server/server.go` exposes raw internal errors to clients (`Message: err.Error()`), while parse/invalid-request errors are normalized strings; HTTP transport always emits 400 for any RPC error, collapsing error classes.",
"`internal/ai/openai.go` does not check HTTP status before JSON decode, unlike scraper fetchers in `internal/scraper/external/*.go` and `internal/scraper/openapi.go` that explicitly gate on status codes.",
"`internal/search/engine.go` and `internal/scraper/openapi.go` mix wrapped and passthrough errors in adjacent paths, producing uneven context for operators."
],
"impact_scope": "subsystem",
"fix_scope": "multi_file_refactor",
"confidence": "high"
}
},
"findings": [
{
"dimension": "error_consistency",
"identifier": "rpc_decode_and_response_contract_drift",
"summary": "RPC methods use inconsistent decode and error-response contracts",
"related_files": [
"cmd/serve.go",
"internal/server/server.go"
],
"evidence": [
"`cmd/serve.go` ignores JSON decode errors in `devour_query`/`devour_sync` but returns decode errors in `devour_scrape`/`devour_ask`.",
"`internal/server/server.go` returns raw `err.Error()` in RPC payloads and maps all RPC errors to HTTP 400 in `writeRPC`."
],
"suggestion": "Define one RPC error policy: always validate/decode params the same way, map known classes to stable RPC codes/messages, and map transport HTTP statuses by error class (client input vs internal failure).",
"confidence": "high",
"impact_scope": "subsystem",
"fix_scope": "multi_file_refactor"
},
{
"dimension": "error_consistency",
"identifier": "serve_status_swallows_errors_then_dereferences_nil",
"summary": "Status handler ignores errors and can panic from nil stats",
"related_files": [
"cmd/serve.go",
"internal/search/engine.go"
],
"evidence": [
"`cmd/serve.go` uses `state, _ := projectstate.LoadSourceState(...)` and `idxStats, _ := engine.EnsureIndexed(ctx)` in `devour_status`.",
"The same block unconditionally reads `idxStats.Documents` and `idxStats.LastIndexedAt`, which is unsafe if `EnsureIndexed` returned an error."
],
"suggestion": "Handle both errors explicitly in `devour_status`; return structured partial-status with an error field or fail the method uniformly, but do not ignore and dereference.",
"confidence": "high",
"impact_scope": "module",
"fix_scope": "single_edit"
},
{
"dimension": "error_consistency",
"identifier": "openai_http_error_path_not_normalized",
"summary": "OpenAI client lacks explicit HTTP status error handling",
"related_files": [
"internal/ai/openai.go",
"internal/scraper/openapi.go",
"internal/scraper/external/astrodocs.go"
],
"evidence": [
"`internal/ai/openai.go` decodes response bodies directly and only checks `embeddingResp.Error`/`chatResp.Error`; non-2xx responses without expected JSON become generic decode errors.",
"`internal/scraper/openapi.go` and external scrapers explicitly validate HTTP status before body parsing and return explicit HTTP status errors."
],
"suggestion": "Add explicit non-2xx handling in both OpenAI request paths: include status code, bounded response body excerpt, and endpoint context before JSON decode.",
"confidence": "high",
"impact_scope": "module",
"fix_scope": "multi_file_refactor"
},
{
"dimension": "error_consistency",
"identifier": "mixed_wrapping_vs_passthrough_in_core_flows",
"summary": "Adjacent paths alternate between wrapped and raw error returns",
"related_files": [
"internal/search/engine.go",
"internal/scraper/openapi.go",
"internal/config/config.go"
],
"evidence": [
"`internal/search/engine.go` frequently returns raw errors (`return nil, err`) from filesystem/index operations.",
"`internal/scraper/openapi.go` similarly passes through request/file errors raw in `readSpec`, while other branches wrap with operation context.",
"`internal/config/config.go` demonstrates contextual wrapping style (`read config`, `parse config`), creating drift against less-informative paths."
],
"suggestion": "Adopt a package-level rule: wrap external boundary failures with operation context (read/write/parse/network) and preserve `%w`; apply consistently across search/openapi paths.",
"confidence": "medium",
"impact_scope": "subsystem",
"fix_scope": "multi_file_refactor"
},
{
"dimension": "error_consistency",
"identifier": "scanner_pipeline_fail_open_is_inconsistent",
"summary": "Quality scan path mixes fail-open and fail-fast behaviors",
"related_files": [
"internal/quality/scanner.go",
"internal/quality/plugins/go/analyzers/test_coverage.go",
"internal/quality/plugins/go/analyzers/detectors.go"
],
"evidence": [
"`internal/quality/scanner.go` logs detector failures and continues, silently reducing coverage of reported findings.",
"`test_coverage.go` returns `(nil, nil)` for missing `go` tool or missing generated coverage file, while other detector failures return explicit errors.",
"`detectors.go` has parse/count paths that silently `continue` on per-file errors, further mixing behavior."
],
"suggestion": "Standardize detector error semantics with typed outcomes (hard error, soft-skip with reason, per-file skip count) and surface these in scan results so degraded scans are explicit.",
"confidence": "medium",
"impact_scope": "subsystem",
"fix_scope": "architectural_change"
}
]
}