xiaohongshu
xiaohongshu
error-handling-audit
Audits Go code for error handling best practices - proper wrapping with %w, preserved context, meaningful messages, no error swallowing. Use before committing Go code or during error handling reviews.
Full skill instructions
Audit Go code for error handling best practices based on RMS Go coding standards. This skill ensures errors are properly wrapped, context is preserved, and error handling follows idiomatic Go patterns.
Golden Rule: Always wrap errors with fmt.Errorf(..., %w, err) to preserve error chain for errors.Is() and errors.As().
Good Pattern:
func FetchTask(ctx rms.Ctx, id string) (*Task, error) {
task, err := db.GetTask(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to fetch task %s: %w", id, err)
}
return task, nil
}
Bad Patterns:
// ❌ Using %v (destroys error chain)
return nil, fmt.Errorf("failed to fetch task: %v", err)
// ❌ No wrapping at all
return nil, err
// ❌ String concatenation
return nil, errors.New("failed to fetch task: " + err.Error())
CRITICAL EXCEPTIONS:
%v at API boundaries where error chain should not leak%v for logging where you want formatted outputGolden Rule: Error messages must provide enough context to debug issues without source code access.
Good Context:
// Include relevant IDs, values, operation
return fmt.Errorf("failed to update task %s for partner %s: %w", taskID, partnerID, err)
// Include what was expected vs actual
return fmt.Errorf("expected task state 'active', got '%s': %w", task.State, err)
Bad Context:
// ❌ Too vague
return fmt.Errorf("operation failed: %w", err)
// ❌ No context
return fmt.Errorf("error: %w", err)
// ❌ Missing critical IDs
return fmt.Errorf("failed to update task: %w", err)
Golden Rule: Follow consistent error message formatting for operational clarity.
Format Standards:
Good Messages:
"failed to fetch task %s"
"invalid partner ID: must be non-empty"
"task %s not found in workflow %s"
"cannot transition task from %s to %s"
Bad Messages:
"Failed to fetch task" // ❌ Capitalized
"task not found." // ❌ Trailing period
"couldn't get the task" // ❌ Informal contraction
"Error fetching task!" // ❌ Exclamation, capitalized
Golden Rule: Never silently ignore errors. Log or return every error.
Acceptable Patterns:
// Return error
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
// Log and continue (with justification)
if err := cache.Set(key, value); err != nil {
// Non-critical: cache miss acceptable
logger.Warn("cache set failed", "error", err)
}
// Explicitly ignore with comment
_ = file.Close() // Error already handled in deferred cleanup
Unacceptable Patterns:
// ❌ Silent ignore
err := doSomething()
// ❌ Blank identifier without comment
_ = doSomething()
// ❌ Ignored in conditional
if doSomething() != nil {
// No handling
}
Golden Rule: Use appropriate error creation method for the situation.
When to use what:
// Simple static error - use errors.New()
errors.New("task ID required")
// Error with formatting - use fmt.Errorf()
fmt.Errorf("invalid task ID: %s", id)
// Wrapping existing error - use fmt.Errorf with %w
fmt.Errorf("failed to save task: %w", err)
// Sentinel error (for errors.Is) - define as var
var ErrTaskNotFound = errors.New("task not found")
RMS Standards:
github.com/pkg/errors - use stdlib onlycommonpb.Error for gRPC error responsesGolden Rule: No panics except during program startup/initialization.
Acceptable Panic:
func init() {
if os.Getenv("REQUIRED_VAR") == "" {
panic("REQUIRED_VAR environment variable not set")
}
}
Unacceptable Panic:
func ProcessTask(task *Task) {
if task == nil {
panic("task is nil") // ❌ Use error return instead
}
}
# Find all Go files (exclude tests for now, as they have different rules)
find . -name "*.go" -not -path "*/vendor/*" -not -path "*/mock*" -not -path "*_test.go"
Use Read tool to examine Go files, focusing on:
if err != nil)errors.New, fmt.Errorf)For each error handling instance, check:
A. Error Wrapping
fmt.Errorf calls with error arguments%w (good) or %v/%s (bad)%v or %s with error argumentsreturn err)B. Error Context
C. Error Message Format
D. Error Swallowing
err :=, err =)_, verify explanatory comment existsE. Error Creation
F. Panic Usage
panic() callsCreate a structured report:
## Error Handling Audit: [file_path]
### ✅ Functions With Correct Error Handling
- `FunctionName` ([file:line]) - Proper wrapping, good context
### 🚨 CRITICAL Issues
#### Error Wrapping with %v Instead of %w
- **Function**: `FetchTask` ([file:line])
- **Issue**: Using %v destroys error chain
- **Location**: Line X: `fmt.Errorf("failed: %v", err)`
- **Fix**: Change to `fmt.Errorf("failed: %w", err)`
#### Error Swallowing
- **Function**: `ProcessTask` ([file:line])
- **Issue**: Error assigned but never checked
- **Location**: Line X: `err := doSomething()`
- **Fix**: Add error check or use `_` with comment
#### Panic in Runtime Code
- **Function**: `UpdateTask` ([file:line])
- **Issue**: Panic used outside initialization
- **Location**: Line X: `panic("task is nil")`
- **Fix**: Return error instead
### ⚠️ HIGH Priority Issues
#### Insufficient Error Context
- **Function**: `SaveTask` ([file:line])
- **Issue**: Error message lacks identifiers
- **Location**: Line X: `fmt.Errorf("save failed: %w", err)`
- **Fix**: Add task ID: `fmt.Errorf("failed to save task %s: %w", taskID, err)`
#### Unwrapped Error Return
- **Function**: `DeleteTask` ([file:line])
- **Issue**: Error returned without wrapping
- **Location**: Line X: `return err`
- **Fix**: Add context: `return fmt.Errorf("failed to delete task %s: %w", taskID, err)`
### ℹ️ MEDIUM Priority Issues
#### Error Message Formatting
- **Function**: `ValidateTask` ([file:line])
- **Issue**: Capitalized error message
- **Location**: Line X: `errors.New("Task is invalid")`
- **Fix**: Lowercase: `errors.New("task is invalid")`
#### Suboptimal Error Creation
- **Function**: `CheckTask` ([file:line])
- **Issue**: Using fmt.Errorf without formatting
- **Location**: Line X: `fmt.Errorf("invalid task")`
- **Fix**: Use simpler: `errors.New("invalid task")`
For each issue, provide:
#### Example Fix: Error Wrapping
**Before** (destroys error chain):
```go
func FetchTask(ctx rms.Ctx, id string) (*Task, error) {
task, err := db.GetTask(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to fetch task: %v", err) // ❌
}
return task, nil
}
```
After (preserves error chain):
func FetchTask(ctx rms.Ctx, id string) (*Task, error) {
task, err := db.GetTask(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to fetch task %s: %w", id, err) // ✅
}
return task, nil
}
Why: Using %w preserves the error chain for errors.Is() and errors.As(), and adds task ID for debugging context.
### Step 6: Summary Statistics
```markdown
## Summary
- Files audited: X
- Functions checked: Y
- Issues found: Z
- CRITICAL: A (must fix before commit)
- HIGH: B (should fix before commit)
- MEDIUM: C (fix during refactoring)
- Clean functions: W
This skill is invoked by:
quality-check skill for Go projectssafe-commit skill (via quality-check)# Manual invocation
/skill error-handling-audit
# Automatic invocation via quality-check
/skill quality-check # Detects Go project, invokes error-handling-audit
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience