DEV Community

loading...

Simple Idea for Improving Error Handling of Go

chenge
Ruby, and learn Rust, Go, Elixir, Erlang...
・1 min read

Following is normal code, repeat too much, not so good.

_, err = fd.Write(p0[a:b])
if err != nil {
    return err
}
_, err = fd.Write(p1[c:d])
if err != nil {
    return err
}
_, err = fd.Write(p2[e:f])
if err != nil {
    return err
}

Improved code:

type errWriter struct {
    w   io.Writer
    err error
}

func (ew *errWriter) write(buf []byte) {
    if ew.err != nil {
        return
    }
    _, ew.err = ew.w.Write(buf)
}

ew := &errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
if ew.err != nil {
    return ew.err
}

It looks better now by adding another level.

Do you think so?

End and Ref

Repeat Error Handling in Go, a Chinese post.

Discussion (6)

Collapse
krusenas profile image
Karolis

I guess this would be alright if you don't need to actually handle any errors and functions that you call are unrelated. If your functions return a value (that you are going to use) and an error, you probably can't just log an error and continue as that returned value is likely to be nil.

Consider:


users, err := getUsers()
if err != nil {
    // can't just log an error as the 'users' is going to be used
    return err
}
banned, err := banUsers(users)
if err != nil {
    return err
}
_, err := unbanUSers(banned)

And in a scenario where you don't handle any errors, you can also just append them to a slice of errors and decide what you want to do with them in the end :)

Otherwise, handle errors as the official docs suggest :)

Collapse
xlebenny profile image
Benny Leung • Edited

I love panic

Because it can stop the immediately,
But this not is golang suggested practices :(

func ThrowIfError(err error) {
    if err != nil {
        panic(err)
    }
}


_, err = fd.Write(p0[a:b])
ThrowIfError(err)

_, err = fd.Write(p0[c:d])
ThrowIfError(err)

_, err = fd.Write(p0[e:f])
ThrowIfError(err)

It look like a block, easy to copy
(I love DRY, but golang hard to do it)

Collapse
madhadron profile image
Fred Ross

Congratulations, you've just discovered the Maybe monad!

I prefer the unwrapped version in Go because the cases where this is likely to be useful will be surrounded by cases where you're checking errors from other things than writers, and putting this layer in means a sudden jump in the abstractions employed, which makes the code less readable.

Collapse
chenge profile image
chenge Author

could you show some code?

Collapse
theodesp profile image
Theofanis Despoudis

This is a common pattern see the error handling section here dave.cheney.net/practical-go/prese...

Collapse
chenge profile image
chenge Author

Good writing, I'll read it.