tableau icon indicating copy to clipboard operation
tableau copied to clipboard

ecode: add `xerrors.Is` API to check ecode in error

Open wenchy opened this issue 2 years ago • 0 comments

  1. Implement custom xerrors package with advanced features, based on source code from https://pkg.go.dev/errors and https://github.com/rotisserie/eris
  2. Add APIs to xerrors/error.go :
// Is reports whether any error in err's tree matches code.
func Is(err error, code tableaupb.Code) bool {
	return Code(err) == code
}
// Code returns the top-level code wrapped in error in err's tree.
func Code(err error) tableaupb.Code {
	if err == nil {
		return tableaupb.Code_SUCCESS
	}
	for err != nil {
		cause, ok := err.(xcauser)
		if !ok {
			break
		}
		if w, ok := err.(*withCode); ok {
			return w.Code()
		}
		err = cause.Cause()
	}
	return tableaupb.Code_ERR_UNKNOWN
}

Customizing error tests with Is and As methods

See The Go Blog: Working with Errors in Go 1.13

The errors.Is function examines each error in a chain for a match with a target value. By default, an error matches the target if the two are equal. In addition, an error in the chain may declare that it matches a target by implementing an Is method.

As an example, consider this error inspired by the Upspin error package which compares an error against a template, considering only fields which are non-zero in the template:

type Error struct {
    Path string
    User string
}

func (e *Error) Is(target error) bool {
    t, ok := target.(*Error)
    if !ok {
        return false
    }
    return (e.Path == t.Path || t.Path == "") &&
           (e.User == t.User || t.User == "")
}

if errors.Is(err, &Error{User: "someuser"}) {
    // err's User field is "someuser".
}

The errors.As function similarly consults an As method when present.

Solution

Use protobuf enum to define error code in proto/tableau/protobuf/internal/code.proto:

enum Code {
  ERR_UNKNOWN = -1; 

  OK = 0; 

  ERR_SHEET_NOT_FOUND = 1;
  // ...
}

References

wenchy avatar Aug 02 '23 08:08 wenchy