go.bare_recover
Correctness
High
Detects recover() calls that catch panics without logging or re-panicking, silently hiding errors.
Why It Matters
Section titled “Why It Matters”Bare recover calls:
- Hide bugs — Panics indicate serious problems that need attention
- Lose context — No logs means no way to debug issues
- Mask failures — Operations silently fail without notification
- Delay fixes — Problems go unnoticed until they cascade
Example
Section titled “Example”// ❌ Before (swallows panic)func handler() { defer func() { recover() // Panic is silently ignored }() riskyOperation()}// ✅ After (logs and handles)func handler() { defer func() { if r := recover(); r != nil { log.Error("panic recovered", "error", r, "stack", string(debug.Stack())) // Optionally re-panic or return error } }() riskyOperation()}What Unfault Detects
Section titled “What Unfault Detects”recover()without checking return valuerecover()without logging- Naked
defer recover()patterns - Silent panic suppression
Auto-Fix
Section titled “Auto-Fix”Unfault generates patches that add proper panic handling:
defer func() { if r := recover(); r != nil { // Log with stack trace log.Error("panic recovered", "error", r, "stack", string(debug.Stack()))
// Convert to error if possible err = fmt.Errorf("panic: %v", r) }}()When to Recover
Section titled “When to Recover”// HTTP handler - prevent one bad request from crashing serverfunc panicMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer func() { if r := recover(); r != nil { log.Error("HTTP handler panic", "path", r.URL.Path, "error", r) http.Error(w, "Internal Server Error", 500) } }() next.ServeHTTP(w, r) })}