Blog

đŸ€” Why Error Handling in Go Is Different

Go doesn’t use exceptions. Instead, functions that can fail typically return an error as the last return value:

go

CopyEdit

func ReadFile(path string) ([]byte, error) {    // implementation }

This style may look repetitive at first, but it offers:

✅ Predictable control flow

✅ Explicit error handling

✅ Simpler debugging

Go encourages you to handle errors as they happen, rather than rely on deferred panic recovery or centralized error traps.

đŸ§± Basic Error Handling Pattern in Go

go

CopyEdit

data, err := ReadFile("data.txt") if err != nil {    log.Fatal(err) } fmt.Println(string(data))

This pattern—check the error, handle it, and continue—is idiomatic and encouraged by the Go community.

🧰 Creating and Returning Errors

Using errors.New:

go

CopyEdit

import "errors" func divide(a, b int) (int, error) {    if b == 0 {        return 0, errors.New("cannot divide by zero")    }    return a / b, nil }

Using fmt.Errorf for Formatting:

go

CopyEdit

import "fmt" return 0, fmt.Errorf("failed to divide %d by %d: %w", a, b, err)

Use %w to wrap errors—useful for debugging or tracing root causes.

🧠 Idiomatic Go: Always Handle the Error Immediately

Bad:

go

CopyEdit

data, _ := ReadFile("file.txt")

Good:

go

CopyEdit

data, err := ReadFile("file.txt") if err != nil {    return err }

Using _ ignores the error and is discouraged unless you have a very specific reason (e.g., test code or discard intentionally).

đŸ§© Custom Error Types for Better Context

Create structured errors using custom types:

go

CopyEdit

type NotFoundError struct {    Resource string } func (e *NotFoundError) Error() string {    return fmt.Sprintf("%s not found", e.Resource) }

Now you can use type assertions to handle errors differently:

go

CopyEdit

err := getResource() if e, ok := err.(*NotFoundError); ok {    fmt.Println("Handle not found:", e.Resource) }

đŸ§” Error Wrapping and Unwrapping (Go 1.13+)

Go 1.13 introduced native support for error chains via errors.Is and errors.As.

Wrapping:

go

CopyEdit

return fmt.Errorf("read config: %w", err)

Unwrapping:

go

CopyEdit

if errors.Is(err, os.ErrNotExist) {    fmt.Println("File does not exist") }

Type checking:

go

CopyEdit

var pathErr *os.PathError if errors.As(err, &pathErr) {    fmt.Println("Error occurred at path:", pathErr.Path) }

đŸš« Avoid These Common Mistakes

❌ Ignoring errors (_)

❌ Overusing panic/recover (only for truly exceptional cases)

❌ Writing overly generic errors like return errors.New("failed")

❌ Returning wrapped errors without meaningful context

✅ Best Practices for Error Handling in Go

Handle errors as close to their source as possible

Use fmt.Errorf with %w for wrapping context

Use errors.Is() and errors.As() for comparison

Create custom error types for structured handling

Avoid panic() unless in initialization failures or truly unrecoverable errors

Log stack trace or full error chain in production

🛠 Useful Go Packages for Error Handling

errors – Built-in package for wrapping and unwrapping

github.com/pkg/errors – Legacy favorite (still used for rich context)

github.com/hashicorp/go-multierror – Combine multiple errors

github.com/cockroachdb/errors – Advanced stack-tracing and telemetry

đŸ§Ș Real-World Use Case Example

go

CopyEdit

func LoadConfig(file string) error {    content, err := os.ReadFile(file)    if err != nil {        return fmt.Errorf("unable to read config %s: %w", file, err)    }    return nil }

In your main function:

go

CopyEdit

err := LoadConfig("config.yaml") if err != nil {    log.Fatalf("startup failed: %v", err) }

Clean, contextual, and idiomatic.

🏁 Conclusion: Write Go Errors the Go Way

Error handling in Go may seem verbose, but it’s designed for clarity and control. By following idiomatic practices—like checking errors explicitly, wrapping with context, and using custom types—you’ll write more reliable and maintainable software.

In Go, handling errors well isn't just encouraged—it's part of the language’s philosophy.

visit our website www.codriteit.com


About author



Comments


Scroll to Top