DEV Community

Ashomondi
Ashomondi

Posted on

ERROR HANDLING IN GO

Errors, Panic and Recover
Error handling is one of the most important parts of software development. Programs interact with files, networks, databases, APIs and users and all of these can fail. A file may not exist, a network request mat time out or invalid input may be provided.

Different programming languages handles errors differently like exceptions with catch blocks but go takes a different approach. Go uses simple, explicit and readable instead of hidding error behind exception.

Go uses 3 mechanism for handling failures:

  1. Error - for expected problems.
  2. Panic - for unrecoverable situations.
  3. Recover - for regaining control after a panic.

Errors in Go
Go functions commonly return multiple values. One of these values is often an "error".
The built-in error interface is very small:

type error interface {
Error() string
}
Enter fullscreen mode Exit fullscreen mode

Any type that implements the "Error" method satisfies the error interface.

Why Go Uses Explicit Errors
Go makes error handling to be visible instead of using exceptions.

file, err := os.Open("data.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
Enter fullscreen mode Exit fullscreen mode

Advantages of this is :

  • Errors are easy to trace.
  • Control flow is predictable.
  • Development must think about failures.
  • Programs become easier to debug.

Panic and Recover
These error handling should not be used in normal error.

Panic
This immediately stops normal program execution.

panic("database connection lost")
Enter fullscreen mode Exit fullscreen mode

Recover
It can catch a panic and prevent the program from crashing.

func saafeRun () {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}()
panic("something went wrong")
}
Enter fullscreen mode Exit fullscreen mode

When should panic be used?
It should be used for unrecoverable situations:

  1. corrupted program state
  2. impossible conditions
  3. critical initialization failures

Best practices for error handling in Go
Handle errors immediately

data, err := readData()
if err != nil {
return err
}
process(data)
Enter fullscreen mode Exit fullscreen mode

Add context to Errors

return fmt.Errorf("reading user profile: %w, err)
Enter fullscreen mode Exit fullscreen mode

Context make debugging easier.

Avoid ignoring errors
Use lowercase error messages

errprs.New("connection failed")
Enter fullscreen mode Exit fullscreen mode

Define sentinel errors carefully

var ErrUnathorized = errors.New("unauthorized")
if error.Is(err, ErrUnauthorized)
Enter fullscreen mode Exit fullscreen mode

This pattern is useful for reusable error checks.

Real-World

func processFile(name string)error {
file, err := os.Open(name)
if err != nil {
return fmt.Errorf("opening file %s: %w", name, err)
}
defer file.Close()
return nil
}
Enter fullscreen mode Exit fullscreen mode

This code has good practices:

  • checking errors immediately
  • wrapping errors with context
  • cleaninig resources using defer

Conclusion
Error handling in Go is intentionally simple and explicit. Instead of relying on hidden exception systems, Go encourages developers to treat errors as normal values that must be checked and handled carefully.

Although this approach may initially appear verbose, it leads to:

  • clearer code
  • predictable behavior
  • easier debugging
  • more reliable software

Understanding proper error handling is essential for writing professional Go applications. Once mastered, it becomes one of Go’s greatest strengths because it encourages developers to build systems that fail gracefully instead of unexpectedly crashing.

Top comments (1)

Collapse
 
ashomondi profile image
Ashomondi

As a beginner learning Go, the if err != nil pattern looked strange compared to exceptions in other languages, but now I understand why Go developers value clarity and simplicity.
Check the article give comments on what to improve or what to add, happy reading.