Skip to content

Code Quality: Silent error handling hides failures #37

@sgaunet

Description

@sgaunet

Description

Errors are silently discarded throughout the codebase using _, violating Go idioms and hiding real issues like broken connections, write failures, and parse errors.

Location

Multiple locations:

  • http-echo.go:57-58 - fmt.Fprintf write errors ignored
  • http-echo.go:63 - ParseForm errors ignored
  • http-echo.go:66 - ReadAll errors ignored
  • http-echo.go:107-236 - All print functions ignore write errors
// Line 57-58: Write errors silently ignored
_, _ = fmt.Fprintf(w, "\n=== REQUEST COMPLETED ===")
_, _ = fmt.Fprintf(w, "\nProcessing Time: %v\n", time.Since(startTime))

// Line 63: Parse errors ignored
_ = r.ParseForm()

// Line 66: Read errors ignored
body, _ := io.ReadAll(r.Body)

Impact

  • Severity: MEDIUM
  • Write failures go undetected (broken connections, client timeouts)
  • Form parsing issues hidden (size limits, corrupted data)
  • Body read errors masked (size limits, I/O errors)
  • Difficult to debug production issues
  • Violates Go error handling best practices

Scenarios Where This Matters

  1. Client Disconnects: Client closes connection mid-response, writes fail silently
  2. Proxy Timeouts: Reverse proxy times out, write errors not logged
  3. Resource Limits: Form data exceeds limits, silently ignored
  4. I/O Errors: Disk/network issues during body read, not detected

Recommended Fix

For Write Errors (Low-Priority Logging)

func (h helloWorldhandler) printRequestSummary(w http.ResponseWriter, info requestInfo) {
    if _, err := fmt.Fprintf(w, "=== REQUEST SUMMARY ===\n"); err != nil {
        log.Printf("Write error: %v", err)
        return // Stop writing if client disconnected
    }
    // ... continue with other writes, checking errors
}

Or create a helper:

type errorWriter struct {
    w   http.ResponseWriter
    err error
}

func (ew *errorWriter) fprintf(format string, args ...interface{}) {
    if ew.err != nil {
        return // Already failed, don't continue writing
    }
    _, ew.err = fmt.Fprintf(ew.w, format, args...)
    if ew.err != nil {
        log.Printf("Write error: %v", ew.err)
    }
}

// Usage in ServeHTTP:
ew := &errorWriter{w: w}
h.printRequestSummary(ew, info)
if ew.err != nil {
    return // Client disconnected
}

For Parse Errors

if err := r.ParseForm(); err != nil {
    log.Printf("Form parse error: %v", err)
    // Continue anyway for diagnostic purposes, but log the issue
}

For Body Read Errors

body, err := io.ReadAll(io.LimitReader(r.Body, maxBodySize))
if err != nil {
    log.Printf("Body read error: %v", err)
    body = []byte(fmt.Sprintf("(error reading body: %v)", err))
}

Benefits

  • Early detection of broken connections (stop processing)
  • Visibility into client-side issues
  • Better debugging in production
  • Follows Go best practices
  • Helps identify infrastructure issues (proxies, timeouts)

Testing

  • Test with client that disconnects mid-request
  • Test with very slow clients (write timeout scenarios)
  • Test with malformed form data
  • Review logs for error messages

Priority

Medium - Code quality issue that improves observability and debugging.

Related Issues

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions