Error Handling Guide¶
Error handling differs by usage mode:
CLI Mode¶
Errors are displayed as user-friendly messages without stack traces:
$ cov-loupe summary nonexistent.rb
File error: No coverage data found for the specified file
$ cov-loupe s nonexistent.rb
File error: No coverage data found for the specified file
For debugging, use the --error-mode debug flag to include stack traces in log output and display the first 5 lines of the backtrace in CLI output:
$ cov-loupe --error-mode debug summary nonexistent.rb
$ cov-loupe --error-mode debug s nonexistent.rb
Library Mode¶
Calls to CovLoupe::CoverageModel raise custom exceptions you can handle programmatically:
handler = CovLoupe::ErrorHandlerFactory.for_library # disables CLI-style logging
context = CovLoupe.create_context(error_handler: handler)
CovLoupe.with_context(context) do
model = CovLoupe::CoverageModel.new
begin
model.summary_for('missing.rb')
rescue CovLoupe::FileError => e
puts "Handled gracefully: #{e.user_friendly_message}"
end
end
Available exception classes: - CovLoupe::Error - Base error class - CovLoupe::FileError - Requested file not in coverage data - CovLoupe::FileNotFoundError - File does not exist on disk (subclass of FileError) - CovLoupe::FilePermissionError - File permission denied (subclass of FileError) - CovLoupe::CoverageDataError - Invalid or missing coverage data - CovLoupe::ResultsetNotFoundError - Coverage data file not found (subclass of CoverageDataError) - CovLoupe::CoverageDataStaleError - Coverage data is stale (when raise_on_stale: true) - CovLoupe::CoverageDataProjectStaleError - Project-wide staleness error - CovLoupe::ConfigurationError - Configuration problems - CovLoupe::UsageError - Command usage errors
MCP Server Mode¶
Three failure categories map to two response shapes:
- Argument validation - Missing required arguments and invalid enum values such as
formatorsort_orderreturn atools/callresult withisError: true. The MCP SDK rejects these requests before the tool implementation runs. - Tool execution - Bad paths, invalid predicates, stale coverage, and similar cov-loupe errors return a
tools/callresult withisError: true. - Protocol and dispatch - Malformed JSON-RPC requests, unknown methods, and unknown tools return a top-level JSON-RPC
errorresponse rather than atools/callresult.
MCP clients can detect argument-validation and tool-execution failures programmatically by checking the result's isError field. Protocol- and dispatch-level failures do not contain a tool result.
- Logging enabled - Tool-execution errors handled by cov-loupe go to
cov_loupe.login the current directory by default; MCP SDK argument-validation failures do not reach cov-loupe's logger - Clean error messages - User-friendly messages, no stack traces by default
Custom Error Handlers¶
Library usage can opt into different logging behavior by installing a custom handler on the active context:
handler = CovLoupe::ErrorHandler.new(error_mode: :log)
context = CovLoupe.create_context(error_handler: handler)
CovLoupe.with_context(context) do
model = CovLoupe::CoverageModel.new
model.summary_for('lib/cov_loupe/model/model.rb')
end
Stale Coverage Errors¶
When strict staleness checking is enabled (--raise-on-stale), the model (and CLI) raise a CoverageDataStaleError if a source file appears newer than the coverage data or the line counts differ.
- Enable per instance:
CovLoupe::CoverageModel.new(raise_on_stale: true)
The error message is detailed and includes:
- File and Coverage times (UTC and local) and line counts
- A delta indicating how much newer the file is than coverage
- The absolute path to the
.resultset.jsonused
Example excerpt:
Coverage data stale: Coverage data appears stale for lib/foo.rb
File - time: 2025-09-16T14:03:22Z (local 2025-09-16T07:03:22-07:00), lines: 226
Coverage - time: 2025-09-15T21:11:09Z (local 2025-09-15T14:11:09-07:00), lines: 220
Delta - file is +123s newer than coverage
Resultset - /path/to/project/coverage/.resultset.json