DEV Community

Moksh
Moksh

Posted on

Panic vs. Error: When to Use Which in Golang?

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
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ’ก 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
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”ฅ 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")
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”น 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()
}
Enter fullscreen mode Exit fullscreen mode

โš ๏ธ 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)