It's not 75% of the code-base. During the error handling proposals, the Go team analyzed a large corpus of Go, and it turns out people drastically overstate how much error handling contributes to the line count.
func CopyFile(src, dst string) error {
r, err := os.Open(src)
if err != nil {
return err
}
defer r.Close()
w, err := os.Create(dst)
if err != nil {
return err
}
defer w.Close()
if _, err := io.Copy(w, r); err != nil {
return err
}
if err := w.Close(); err != nil {
return err
}
} if r, err := os.Open(src); err != nil {
return err
}
defer r.Close()
But then r is not in scope for the r.Close properYou could have smaller discrete functions that abstract the handling of each action a little bit and be more reusable, or is that not possible in Go
These shorter functions need to signal their failure somehow, so calling them looks exactly like the example.