Error handling best practices

Handle errors in Go by explicitly checking return values and using the error interface to manage failures gracefully.

Handle errors explicitly by checking the error return value immediately after a function call and acting on it before proceeding. This pattern prevents silent failures and allows you to log context or recover gracefully.

f, err := os.Open("filename.ext")
if err != nil {
    log.Fatal(err)
}
// proceed with file f

For custom errors, define a type implementing the error interface and use fmt.Errorf to add context:

type NegativeSqrtError float64
func (f NegativeSqrtError) Error() string {
    return fmt.Sprintf("math: square root of negative number %g", float64(f))
}

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, NegativeSqrtError(f)
    }
    // implementation
}

Use type assertions to inspect specific error types when needed:

if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
    time.Sleep(1e9)
    continue
}
if err != nil {
    log.Fatal(err)
}