Improve error messages with recovery suggestions #25

Closed
opened 2026-01-03 23:39:50 +00:00 by KofTwentyTwo · 2 comments
KofTwentyTwo commented 2026-01-03 23:39:50 +00:00 (Migrated from github.com)

Part of #12

User Story

As a qctl user, I want clear error messages with recovery suggestions so that I can fix problems without searching documentation.

Design

Error Categories

Category Example Recovery Suggestion
Template not found qqq-invalid Show similar templates, suggest qctl qqq list
Network error Connection refused Check internet, suggest --offline if cached
Manifest error Invalid YAML Show line number, suggest schema docs
Render error Invalid variable Show variable name, available variables
Transform error Directory not found Show expected path, check template structure
Validation error Pattern mismatch Show expected format, valid examples

Error Message Format

Error: Template 'qqq-webapi' not found

Did you mean?
  • qqq-web-api

Available templates: qctl qqq list
Error: Failed to render template at line 42: Unknown variable 'packagename'

Available variables:
  • packageName
  • appName
  • groupId

Tip: Variable names are case-sensitive

Exit Codes

Use semantic exit codes from ExitCodes.java:

  • 5 = NOT_FOUND (template not found)
  • 6 = VALIDATION (invalid input)
  • 3 = NETWORK (connection issues)

Suggestion Engine

Implement fuzzy matching for "did you mean?" suggestions:

  • Levenshtein distance for typo detection
  • Prefix matching for partial names
  • Case-insensitive matching

Files to Create/Modify

File Action Description
TemplateError.java Create Structured error with suggestions
ErrorFormatter.java Create Formats errors with recovery hints
SuggestionEngine.java Create Fuzzy matching for suggestions
InitCommand.java Modify Use structured errors
ListCommand.java Modify Use structured errors
TemplateEngine.java Modify Capture context for errors

Implementation Tasks

  • Create TemplateError class with category, message, suggestions
  • Create ErrorFormatter for consistent error output
  • Implement SuggestionEngine with Levenshtein distance
  • Add "did you mean?" for template names
  • Add "did you mean?" for variable names in render errors (deferred)
  • Include line numbers in YAML parse errors (deferred)
  • Include file paths in transform errors (deferred)
  • Add network error recovery suggestions
  • Map all errors to appropriate exit codes
  • Add --verbose flag for stack traces
  • Test error messages for all failure scenarios
  • Document common errors and solutions (deferred to docs)

Acceptance Criteria

  • Typos suggest correct template names
  • Unknown variables suggest similar names (deferred)
  • YAML errors show line numbers (deferred)
  • Network errors suggest offline mode
  • All errors have actionable suggestions
  • Exit codes are semantic and documented
  • --verbose shows full stack trace
  • Error messages fit terminal width
Part of #12 ## User Story As a **qctl user**, I want clear error messages with recovery suggestions so that I can fix problems without searching documentation. ## Design ### Error Categories | Category | Example | Recovery Suggestion | |----------|---------|---------------------| | Template not found | `qqq-invalid` | Show similar templates, suggest `qctl qqq list` | | Network error | Connection refused | Check internet, suggest `--offline` if cached | | Manifest error | Invalid YAML | Show line number, suggest schema docs | | Render error | Invalid variable | Show variable name, available variables | | Transform error | Directory not found | Show expected path, check template structure | | Validation error | Pattern mismatch | Show expected format, valid examples | ### Error Message Format ``` Error: Template 'qqq-webapi' not found Did you mean? • qqq-web-api Available templates: qctl qqq list ``` ``` Error: Failed to render template at line 42: Unknown variable 'packagename' Available variables: • packageName • appName • groupId Tip: Variable names are case-sensitive ``` ### Exit Codes Use semantic exit codes from `ExitCodes.java`: - 5 = NOT_FOUND (template not found) - 6 = VALIDATION (invalid input) - 3 = NETWORK (connection issues) ### Suggestion Engine Implement fuzzy matching for "did you mean?" suggestions: - Levenshtein distance for typo detection - Prefix matching for partial names - Case-insensitive matching ## Files to Create/Modify | File | Action | Description | |------|--------|-------------| | `TemplateError.java` | Create | Structured error with suggestions | | `ErrorFormatter.java` | Create | Formats errors with recovery hints | | `SuggestionEngine.java` | Create | Fuzzy matching for suggestions | | `InitCommand.java` | Modify | Use structured errors | | `ListCommand.java` | Modify | Use structured errors | | `TemplateEngine.java` | Modify | Capture context for errors | ## Implementation Tasks - [x] Create `TemplateError` class with category, message, suggestions - [x] Create `ErrorFormatter` for consistent error output - [x] Implement `SuggestionEngine` with Levenshtein distance - [x] Add "did you mean?" for template names - [ ] Add "did you mean?" for variable names in render errors (deferred) - [ ] Include line numbers in YAML parse errors (deferred) - [ ] Include file paths in transform errors (deferred) - [x] Add network error recovery suggestions - [x] Map all errors to appropriate exit codes - [x] Add `--verbose` flag for stack traces - [x] Test error messages for all failure scenarios - [ ] Document common errors and solutions (deferred to docs) ## Acceptance Criteria - [x] Typos suggest correct template names - [ ] Unknown variables suggest similar names (deferred) - [ ] YAML errors show line numbers (deferred) - [x] Network errors suggest offline mode - [x] All errors have actionable suggestions - [x] Exit codes are semantic and documented - [x] `--verbose` shows full stack trace - [x] Error messages fit terminal width
KofTwentyTwo commented 2026-01-04 03:11:05 +00:00 (Migrated from github.com)

Implementation Complete

Changes in 30e124d

New files:

  • SuggestionEngine.java - Fuzzy matching using Levenshtein distance with prefix/substring bonuses
  • TemplateError.java - Structured error with category, message, suggestions, hints
  • ErrorFormatter.java - ANSI-colored output with "Did you mean?" and stack trace support
  • Tests: 27 new tests (13 SuggestionEngine, 6 TemplateError, 8 ErrorFormatter)

Modified:

  • InitCommand.java - Integrated error handling with template suggestions
  • ListCommand.java - Consistent error formatting

Features:

  • "Did you mean?" suggestions for mistyped template names
  • --verbose flag shows full stack traces
  • Network errors suggest checking connection
  • All errors map to semantic exit codes

Deferred to future stories:

  • Variable name suggestions in render errors
  • Line numbers in YAML parse errors
  • File paths in transform errors
## Implementation Complete ### Changes in 30e124d **New files:** - `SuggestionEngine.java` - Fuzzy matching using Levenshtein distance with prefix/substring bonuses - `TemplateError.java` - Structured error with category, message, suggestions, hints - `ErrorFormatter.java` - ANSI-colored output with "Did you mean?" and stack trace support - Tests: 27 new tests (13 SuggestionEngine, 6 TemplateError, 8 ErrorFormatter) **Modified:** - `InitCommand.java` - Integrated error handling with template suggestions - `ListCommand.java` - Consistent error formatting **Features:** - "Did you mean?" suggestions for mistyped template names - `--verbose` flag shows full stack traces - Network errors suggest checking connection - All errors map to semantic exit codes **Deferred to future stories:** - Variable name suggestions in render errors - Line numbers in YAML parse errors - File paths in transform errors
KofTwentyTwo commented 2026-01-04 03:34:08 +00:00 (Migrated from github.com)

Completed

Implemented all deferred error message improvements:

1. "Did you mean?" for variable names

  • Added Levenshtein-based suggestions when undefined variables are referenced
  • Shows similar variable names and lists all available variables
  • Example output:
Undefined variable: pacakgeName

Did you mean?
  - packageName

Available variables:
  - packageName
  - appName
  - packagePath

Tip: Variable names are case-sensitive

2. Line numbers in YAML parse errors

  • TemplateManifest.load() now extracts line/column info from Jackson exceptions
  • Example: YAML parse error in template.yaml (line 15, column 3): Unexpected token

3. File paths in transform errors

  • TransformExecutor wraps errors with file context
  • Shows transform pattern and target directory in error messages

All tests pass.

## Completed Implemented all deferred error message improvements: ### 1. "Did you mean?" for variable names - Added Levenshtein-based suggestions when undefined variables are referenced - Shows similar variable names and lists all available variables - Example output: ``` Undefined variable: pacakgeName Did you mean? - packageName Available variables: - packageName - appName - packagePath Tip: Variable names are case-sensitive ``` ### 2. Line numbers in YAML parse errors - `TemplateManifest.load()` now extracts line/column info from Jackson exceptions - Example: `YAML parse error in template.yaml (line 15, column 3): Unexpected token` ### 3. File paths in transform errors - `TransformExecutor` wraps errors with file context - Shows transform pattern and target directory in error messages All tests pass.
Sign in to join this conversation.