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)
}