Fundamentals 5 min read

Mastering Go Error Handling: From Basic Returns to Elegant State Management

The article explains Go's lack of try/catch, demonstrates how to use error return values with examples, shows how to create custom error types, and presents an optimized pattern that aggregates error checks to produce cleaner, more efficient code without performance loss.

ITPUB
ITPUB
ITPUB
Mastering Go Error Handling: From Basic Returns to Elegant State Management

Go does not provide a try/catch mechanism; instead, functions signal errors by returning an error value, typically as the last return parameter. The common pattern is:

n, err := func()
if err != nil {
    // handle error
}

or in a single statement:

if n, err := func(); err != nil {
    // handle error
}

Errors can be created with errors.New("message") or fmt.Errorf("%d can't divide by 0", arg). The error type is an interface defined as:

type error interface {
    Error() string
}

Any type that implements an Error() string method satisfies this interface, allowing custom error types. For example:

type division struct {
    arg int
    str string
}

func (e *division) Error() string {
    return fmt.Sprintf("%d %s", e.arg, e.str)
}

func divideCheck(arg1, arg2 int) error {
    if arg2 == 0 {
        return &division{arg1, "can't divide by 0"}
    }
    return nil
}

A straightforward usage checks each call individually:

func main() {
    if err := divideCheck(4, 2); err != nil {
        fmt.Println(err)
        return
    }
    if err := divideCheck(8, 0); err != nil {
        fmt.Println(err)
        return
    }
}

While functional, this approach repeats error‑handling code for every call. An optimized design stores the first encountered error inside a struct and checks it before further processing:

type division struct {
    err error
}

func (d *division) DivideCheck(arg1, arg2 int) {
    if d.err != nil {
        return
    }
    if arg2 == 0 {
        d.err = fmt.Errorf("%d can't divide by 0", arg1)
        return
    }
}

func (d *division) Err() error { return d.err }

func main() {
    d := new(division)
    d.DivideCheck(4, 2)
    d.DivideCheck(8, 0)
    if d.Err() != nil {
        fmt.Println(d.Err())
    }
}

This version reduces boilerplate, stops further checks after the first error, and incurs negligible performance overhead, demonstrating that Go's error handling can be both clear and elegant when used idiomatically.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendGolangGocustom errorerror-handling
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.