go: proposal: errors: configurable Handle(error) function

Problem

Most of the time in Go if an error occurs it can be returned. There are certain cases when this is not possible, usually go functions.

go func(){
    if err := foo(); err != nil {
        // cannot 'return err' because the function has already returned
    }
}

Packages shouldn’t choose how to handle errors so they end up either squashing the error or making configurable error logging like ErrorLog in httputil.ReverseProxy or http.Server.

Proposal

I propose adding a function errors.Handle(error) that can be called in cases where it is impossible to return an error.

There should be a second function errors.SetHandler(func(error)) that can be called, usually in main, that lets an application choose how to handle an error. (i.e. log, increment a metrics, …)

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 8
  • Comments: 24 (7 by maintainers)

Most upvoted comments

It seems to me that a library can let an application handle an error by simply returning the error.

I think we should decline all the error handling proposals until we are ready to revisit the topic (perhaps not for a few years).

I appreciate that you feel strongly about this issue.

I can’t think of anything else in the Go standard library that works this way. The idea of a global handler just doesn’t seem very Go like to me. This feature is only useful if the standard library itself uses it, but I think that for any specific case in the standard library we would look for some other way to return the error to the application.

What I learn from your example of ioutil.ReadFile is that we should fix that function, not that we should add a global error handling mechanism.

You suggest that shouldn’t want to be opinionated, but in fact Go is an opinionated language, by choice. And the opinionated choice is to return errors. httputil.ReverseProxy is indeed an exception here.

It used to be very common to write programs that work by setting global values, rather than returning things. You could still do this today with:

package globalerr

var Error error

func IsSet() bool {
    return Error != nil
}

And then just set this when you want to in your functions and methods. I don’t think this is a good idea, however. This style of programming turns out to compose poorly and be quite brittle. I don’t think there’s any reason for the language to encourage this approach to errors.