Skip to content

go 2.0 error handling feedback

Cosmos Nicolaou edited this page Sep 4, 2018 · 3 revisions

Currently there is no means for programmatically checking for a specific error in an address space different to the one that generated it. Consider an RPC that returns io.ErrUnexpectedEOF, the underlying RPC system will marshal that error in some way or other, and the client would, ideally, test for that using errors.Is as per the go 2.0 proposal. However, errors.Is will always return false because the == will always fail for the in-address space io.ErroUnexpectedEOF and the unmarshaled return value from the remote RPC. Practically speaking this means that errors can't be read/written from/to other processes. One could argue that this is a corner case and hence best left to application developers to wrap the errors package, however, this would bring back some of the ugliness that you are attempting to avoid. A possible solution could be as follows:

package errors

type Stable interface {
    ID() string
}

func Is(err, target error) bool {
        stable, isStable := err.(Stable)
        id := stable.ID()
	for {
		if err == target {
			return true
		}
                if isStable {
                    if errStable, ok := err.(Stable); ok {
                         if errStable.ID() == id {
                              return true
                         }
                    }
                }
		wrapper, ok := err.(Wrapper)
		if !ok {
			return false
		}
		err = wrapper.Unwrap()
		if err == nil {
			return false
		}
	}
}

Note that ID would typically be .myerror, or at least this how v.io/v23/verror was used.

Clone this wiki locally