Error Handling in Go (Golang)
Go handles errors explicitly using the error
type. Functions that can produce errors return an error
as their last return value. This approach encourages developers to handle errors explicitly, making code more robust and predictable.
Basic Error Handling
Use an if
statement to check for errors after calling a function. This is the most common way to handle errors in Go.
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("example.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
defer file.Close()
fmt.Println("File opened successfully!")
}
Custom Errors
You can create custom errors using the errors.New()
function or by implementing the error
interface. Custom errors are useful for providing more context about the error.
package main
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
Error Wrapping
Go 1.13 introduced error wrapping, which allows you to add context to errors while preserving the original error. Use the fmt.Errorf
function with the %w
verb to wrap errors.
package main
import (
"errors"
"fmt"
)
func processFile(filename string) error {
_, err := os.Open(filename)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
return nil
}
func main() {
err := processFile("nonexistent.txt")
if err != nil {
fmt.Println("Error:", err)
}
}
Panic and Recover
Use panic
to stop the normal execution of a program and recover
to regain control. This is typically used for handling unexpected errors or critical failures.
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("Something went wrong!")
}
Best Practices
- Handle Errors Explicitly: Always check for errors and handle them appropriately.
- Provide Context: Use error wrapping to add context to errors, making debugging easier.
- Avoid Panic: Use
panic
only for unrecoverable errors. For recoverable errors, return anerror
instead. - Use Custom Errors: Create custom errors for specific error conditions to provide more meaningful error messages.
- Log Errors: Log errors with sufficient context to help diagnose issues in production.