Part of duplicate code analysis: #aw_parent001main
Summary
Connection error handling and diagnostic logging is duplicated across launcher.go, log_helpers.go, and mcp/connection.go. Each file independently logs the command, args, env context, stderr output, and error-type hints using a similar log.Printf("[LAUNCHER] …") block structure. Divergence between these copies means diagnostics may be inconsistent or incomplete depending on which code path triggers the error.
Duplication Details
Pattern: Multi-step connection error diagnostics block
- Severity: Medium
- Occurrences: 3 distinct error-logging blocks across 3 files
- Locations:
internal/launcher/log_helpers.go — logLaunchError function (~lines 36–67)
internal/launcher/launcher.go — timeout branch and goroutine error branch (~lines 143–161)
internal/mcp/connection.go — NewConnection error handling (~lines 108–130)
log_helpers.go (logLaunchError):
logger.LogErrorWithServer(serverID, "backend", "Failed to launch MCP backend server%s: ...", ...)
log.Printf("[LAUNCHER] ❌ FAILED to launch server '%s'%s", serverID, sessionSuffix(sessionID))
log.Printf("[LAUNCHER] Error: %v", err)
log.Printf("[LAUNCHER] Debug Information:")
log.Printf("[LAUNCHER] - Command: %s", serverCfg.Command)
log.Printf("[LAUNCHER] - Args: %v", sanitize.SanitizeArgs(serverCfg.Args))
log.Printf("[LAUNCHER] - Env vars: %v", sanitize.TruncateSecretMap(serverCfg.Env))
log.Printf("[LAUNCHER] - Running in container: %v", l.runningInContainer)
// … hint analysis based on error message content
connection.go (NewConnection error path):
logger.LogErrorMd("backend", "MCP backend connection failed, command=%s, args=%v, error=%v", ...)
log.Printf("❌ MCP Connection Failed:")
log.Printf(" Command: %s", command)
log.Printf(" Args: %v", sanitize.SanitizeArgs(expandedArgs))
log.Printf(" Error: %v", err)
// stderr capture and printing
// executable-not-found hint
// EOF hint
Both blocks:
- Print command + args (sanitized)
- Print the error
- Analyze
err.Error() for known strings ("executable file not found", "EOF", "no such file") and emit hints
- Log stderr if available
Impact Analysis
- Maintainability: Adding a new hint (e.g., for a new Docker error) must be done in both files; easy to miss one
- Bug Risk: Medium — diverged diagnostics mean some code paths give less helpful output to operators
- Code Bloat: ~30 lines × 2–3 occurrences = ~75 lines of largely duplicate diagnostic code
Refactoring Recommendations
-
Extract ConnectionErrorContext + LogConnectionError into a shared helper (e.g., internal/launcher/log_helpers.go already exists as a good home, or a new internal/mcp/errors.go):
type ConnectionErrorContext struct {
ServerID string
SessionID string
Command string
Args []string
Env map[string]string
RunningInContainer bool
IsDirectCommand bool
StartupTimeout time.Duration
StderrOutput string
}
func LogConnectionError(ctx ConnectionErrorContext, err error) {
// Single place for structured + debug logging
// Single place for error-string hint analysis
}
-
Migrate all three sites to call LogConnectionError(...).
-
Estimated effort: ~3 hours to extract, migrate, and test.
Benefits: single place to add/improve diagnostic hints; consistent output format for operators.
Implementation Checklist
Parent Issue
See parent analysis report: #aw_parent001main
Generated by Duplicate Code Detector · ◷
Part of duplicate code analysis: #aw_parent001main
Summary
Connection error handling and diagnostic logging is duplicated across
launcher.go,log_helpers.go, andmcp/connection.go. Each file independently logs the command, args, env context, stderr output, and error-type hints using a similarlog.Printf("[LAUNCHER] …")block structure. Divergence between these copies means diagnostics may be inconsistent or incomplete depending on which code path triggers the error.Duplication Details
Pattern: Multi-step connection error diagnostics block
internal/launcher/log_helpers.go—logLaunchErrorfunction (~lines 36–67)internal/launcher/launcher.go— timeout branch and goroutine error branch (~lines 143–161)internal/mcp/connection.go—NewConnectionerror handling (~lines 108–130)log_helpers.go (logLaunchError):
connection.go (NewConnection error path):
Both blocks:
err.Error()for known strings ("executable file not found","EOF","no such file") and emit hintsImpact Analysis
Refactoring Recommendations
Extract
ConnectionErrorContext+LogConnectionErrorinto a shared helper (e.g.,internal/launcher/log_helpers.goalready exists as a good home, or a newinternal/mcp/errors.go):Migrate all three sites to call
LogConnectionError(...).Estimated effort: ~3 hours to extract, migrate, and test.
Benefits: single place to add/improve diagnostic hints; consistent output format for operators.
Implementation Checklist
ConnectionErrorContextstruct to capture all needed fieldsLogConnectionErrorin a shared locationlog_helpers.go,launcher.go, andconnection.goto use the helpermake testto verify no regressionsParent Issue
See parent analysis report: #aw_parent001main