{ "batch": "Cross-cutting Sweep", "batch_index": 1, "assessments": { "error_consistency": 74.0 }, "dimension_notes": { "error_consistency": { "evidence": [ "Error wrapping is inconsistent across neighboring call paths: `cmd/serve.go` wraps many failures with operation context (e.g. `run devour_query search`), while `runServe` and `handleServeMethod` still return raw errors directly from `loadAppConfig` (`cmd/serve.go:45`, `cmd/serve.go:75`).", "Several lower-level functions return bare underlying errors without context (`internal/scraper/local.go:49`, `internal/scraper/local.go:57`, `internal/config/config.go:207`, `internal/config/config.go:364`) while sibling code in the same files uses contextual wrapping.", "Error classification is string-based in `cmd/ask.go` (`strings.Contains(fetchErr.Error(), \"persistence warning:\")` at line 191), making behavior dependent on message text rather than typed/sentinel error contracts.", "At least one path suppresses error details entirely (`countLOC` returns `0` on read failure in `internal/quality/plugins/go/plugin.go:353-356`), while other analyzer code returns explicit detector errors." ], "impact_scope": "subsystem", "fix_scope": "multi_file_refactor", "confidence": "high" } }, "findings": [ { "dimension": "error_consistency", "identifier": "mixed_wrapped_and_bare_error_propagation", "summary": "Adjacent layers mix contextual wrapping and bare error returns", "related_files": [ "cmd/serve.go", "internal/config/config.go", "internal/scraper/local.go", "cmd/scrape.go" ], "evidence": [ "`cmd/serve.go:87-109` wraps errors with operation labels, but `cmd/serve.go:45` and `cmd/serve.go:75` return raw `loadAppConfig` errors.", "`internal/config/config.go:207` and `:364` return bare errors, while nearby code uses contextual `fmt.Errorf(...: %w)`.", "`internal/scraper/local.go:49`, `:57`, `:104`, `:154`, `:164` return raw errors despite other branches adding context and joins." ], "suggestion": "Adopt a single propagation rule for non-boundary layers: always wrap external/I-O failures with operation context (e.g., `fmt.Errorf(\"load config path: %w\", err)`). Apply this consistently in `cmd/serve.go`, `internal/config/config.go`, and `internal/scraper/local.go`.", "confidence": "high", "impact_scope": "subsystem", "fix_scope": "multi_file_refactor" }, { "dimension": "error_consistency", "identifier": "string_based_error_classification_in_ask_flow", "summary": "Ask flow branches on error message text instead of typed categories", "related_files": [ "cmd/ask.go", "cmd/scrape.go", "internal/server/server.go" ], "evidence": [ "`cmd/ask.go:379` and `:384` encode category in message prefix (`\"persistence warning:\"`).", "`cmd/ask.go:191` uses `strings.Contains(fetchErr.Error(), \"persistence warning:\")` for control flow, coupling behavior to mutable message strings.", "Other modules treat errors opaquely and pass through generic text (`internal/server/server.go:256` returns `err.Error()` to RPC clients), amplifying inconsistency in downstream handling." ], "suggestion": "Introduce typed/sentinel errors for recoverable warning classes (e.g., `var ErrPersistenceWarning`) and use `errors.Is`/`errors.As` in `cmd/ask.go` instead of string matching. Keep human-readable text separate from machine classification.", "confidence": "high", "impact_scope": "module", "fix_scope": "multi_file_refactor" }, { "dimension": "error_consistency", "identifier": "analyzer_error_handling_policy_is_incoherent", "summary": "Analyzer/plugin paths alternate between explicit, wrapped, and silent failures", "related_files": [ "internal/quality/plugins/go/analyzers/detectors.go", "internal/quality/plugins/go/analyzers/advanced.go", "internal/quality/plugins/go/plugin.go" ], "evidence": [ "`internal/quality/plugins/go/analyzers/detectors.go:46-60` converts read failures into synthetic findings (`detector_error`) rather than returning an error.", "`internal/quality/plugins/go/analyzers/advanced.go:242` returns raw parse errors from helper methods without context.", "`internal/quality/plugins/go/plugin.go:353-356` swallows file read failures in `countLOC` by returning `0`, losing failure provenance entirely." ], "suggestion": "Define a consistent analyzer failure contract: either (a) report detector-execution issues as standardized `detector_error` findings with metadata, or (b) return wrapped errors; do not silently coerce errors to default values. Refactor `countLOC` to return `(int, error)` and propagate classification consistently.", "confidence": "medium", "impact_scope": "subsystem", "fix_scope": "architectural_change" } ] }