{ "batch": "Cross-cutting Sweep", "batch_index": 1, "assessments": { "error_consistency": 71.0 }, "dimension_notes": { "error_consistency": { "evidence": [ "Multiple analyzers silently suppress parse/read failures instead of returning contextual errors (internal/quality/plugins/go/analyzers/detectors.go:112-114, 240-245; internal/quality/plugins/go/analyzers/test_coverage.go:211-214).", "Scraper entrypoints mix contextual wrapping and raw passthrough in similar boundary operations (internal/scraper/openapi.go:43-50 returns raw err; internal/scraper/github.go:29-37 returns raw err; internal/scraper/external/nuxtdocs.go:39-45 wraps with %w).", "Several paths collapse structured errors into joined strings, reducing traceability and unwrapping (internal/scraper/web.go:259; internal/scraper/localsearch.go:143; cmd/ask.go:320,340).", "Some runtime errors are dropped and processing continues without durable signal (internal/server/server.go:213 ignores encode error; internal/scraper/local.go:90-93 drops file parse errors; internal/search/engine.go:134-137 skips parse failures)." ], "impact_scope": "subsystem", "fix_scope": "multi_file_refactor", "confidence": "high" } }, "findings": [ { "dimension": "error_consistency", "identifier": "silent_parse_failures_in_analyzers", "summary": "Analyzer parse/read errors are silently converted to no findings.", "related_files": [ "internal/quality/plugins/go/analyzers/detectors.go", "internal/quality/plugins/go/analyzers/test_coverage.go", "internal/quality/scanner.go" ], "evidence": [ "GodStructDetector.analyzeFile returns nil on parser.ParseFile error (detectors.go:112-114).", "DebugLogDetector.analyzeFile also returns nil on parse failure (detectors.go:240-241).", "UntestedFuncDetector returns (nil, nil) when coverage.out read fails (test_coverage.go:211-214), making failure indistinguishable from success.", "Scanner loop logs detector failure and continues (scanner.go:77-79), so detector internals that swallow errors become invisible." ], "suggestion": "Standardize detector contract: return wrapped errors for parse/read failures (`fmt.Errorf(\"parse %s: %w\", path, err)`) and let scanner classify them as detector execution errors instead of empty findings.", "confidence": "high", "impact_scope": "module", "fix_scope": "multi_file_refactor" }, { "dimension": "error_consistency", "identifier": "mixed_error_wrapping_at_scraper_boundaries", "summary": "Scrapers mix raw error passthrough with contextual wrapping.", "related_files": [ "internal/scraper/openapi.go", "internal/scraper/github.go", "internal/scraper/external/nuxtdocs.go" ], "evidence": [ "OpenAPI scraper returns raw `err` from readSpec/parseOpenAPISpec (openapi.go:43-50).", "GitHub scraper returns raw resolveRepo/MkdirTemp errors (github.go:29-37).", "Nuxt external scraper wraps fetch/parse failures with operation context and `%w` (nuxtdocs.go:39-45)." ], "suggestion": "Adopt one boundary rule for scraper packages: every external I/O or parse failure should be wrapped with operation context and `%w` before returning.", "confidence": "high", "impact_scope": "subsystem", "fix_scope": "multi_file_refactor" }, { "dimension": "error_consistency", "identifier": "string_aggregated_errors_lose_causal_chain", "summary": "Aggregated scrape failures are flattened to strings, losing unwrap support.", "related_files": [ "internal/scraper/web.go", "internal/scraper/localsearch.go", "cmd/ask.go" ], "evidence": [ "Web scraper returns `fmt.Errorf(\"web scrape failed: %s\", strings.Join(scrapeErrors, \"; \"))` (web.go:259).", "Local search scraper similarly returns joined string error text (localsearch.go:143).", "ask command accumulates URL/term errors as formatted strings (ask.go:320,340), not typed/wrapped errors." ], "suggestion": "Store and return structured error sets (e.g., `[]error` wrapped via a multi-error type) and only stringify at CLI presentation boundaries.", "confidence": "medium", "impact_scope": "subsystem", "fix_scope": "architectural_change" }, { "dimension": "error_consistency", "identifier": "error_drop_and_continue_without_signal", "summary": "Some failures are intentionally ignored with no traceable signal.", "related_files": [ "internal/server/server.go", "internal/scraper/local.go", "internal/search/engine.go" ], "evidence": [ "Server ignores encode error when writing parse-error RPC response (`_ = out.Encode(...)`) (server.go:213).", "Local scraper drops file conversion errors by returning nil in walk callback (local.go:90-93).", "Search engine skips parseDocFile errors with `continue` and no reporting (engine.go:134-137)." ], "suggestion": "When continuing after non-fatal errors, emit a consistent warning/collector path (counter + sampled log + optional returned diagnostics) so operators can detect degraded runs.", "confidence": "high", "impact_scope": "subsystem", "fix_scope": "multi_file_refactor" } ] }