Error handling in Golang is designed to be explicit and predictable, but a common question arises: "When should I return an error, and when should I use panic?" ๐ค Letโs break it down with some real-world examples!
โ
Use error for Expected Failures
Errors are expected but undesirable situations that a function can recover from, such as:
- File not found
- Invalid user input
- Database connection failure
Example: Handling Errors Gracefully
func readFile(filename string) ([]byte, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %w", filename, err)
}
return data, nil
}
๐ก Here, we return an error instead of crashing the program, allowing the caller to handle it.
๐จ Use panic for Unrecoverable Errors
A panic should only be used when the program is in an irrecoverable state, such as:
- Corrupted memory
- Array index out of bounds
- Nil pointer dereference
Example: When panic is Justified
func mustOpen(filename string) *os.File {
file, err := os.Open(filename)
if err != nil {
panic(fmt.Sprintf("fatal: failed to open file: %v", err))
}
return file
}
๐ฅ This should only be used in critical cases where the program cannot continue safely.
๐ซ Avoid panic in Libraries & APIs
A library should never panic because it forces the entire application to crash. Instead, return an error and let the caller decide how to handle it.
// Bad: Causes the entire program to crash
func fetchData() {
panic("Service unavailable!")
}
// Good: Returns an error, allowing the caller to decide what to do
func fetchData() error {
return errors.New("service unavailable")
}
๐น Libraries should be gracefulโlet the user of your code decide what to do!
๐ก๏ธ Use recover() to Catch Panics (Only If Necessary!)
If you must use panic, you can recover from it to prevent a complete crash:
func safeFunction() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
panic("Something went terribly wrong!") // Won't crash due to recover()
}
โ ๏ธ Use recover() wiselyโit should only be used in top-level functions, like middleware in web apps.
๐ฏ Key Takeaways
โ Return error for expected failures that a caller can handle.
๐ฅ Use panic only for critical, unrecoverable errors.
๐ซ Avoid panic in librariesโreturn errors instead.
๐ก๏ธ Use recover() carefully to prevent crashing in unavoidable cases.
By following these best practices, youโll write more stable and maintainable Golang applications! ๐โจ
Top comments (0)