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
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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
qqq-invalidqctl qqq list--offlineif cachedError Message Format
Exit Codes
Use semantic exit codes from
ExitCodes.java:Suggestion Engine
Implement fuzzy matching for "did you mean?" suggestions:
Files to Create/Modify
TemplateError.javaErrorFormatter.javaSuggestionEngine.javaInitCommand.javaListCommand.javaTemplateEngine.javaImplementation Tasks
TemplateErrorclass with category, message, suggestionsErrorFormatterfor consistent error outputSuggestionEnginewith Levenshtein distance--verboseflag for stack tracesAcceptance Criteria
--verboseshows full stack traceImplementation Complete
Changes in
30e124dNew files:
SuggestionEngine.java- Fuzzy matching using Levenshtein distance with prefix/substring bonusesTemplateError.java- Structured error with category, message, suggestions, hintsErrorFormatter.java- ANSI-colored output with "Did you mean?" and stack trace supportModified:
InitCommand.java- Integrated error handling with template suggestionsListCommand.java- Consistent error formattingFeatures:
--verboseflag shows full stack tracesDeferred to future stories:
Completed
Implemented all deferred error message improvements:
1. "Did you mean?" for variable names
2. Line numbers in YAML parse errors
TemplateManifest.load()now extracts line/column info from Jackson exceptionsYAML parse error in template.yaml (line 15, column 3): Unexpected token3. File paths in transform errors
TransformExecutorwraps errors with file contextAll tests pass.