func Is(err, target error) bool {
	if target == nil {
		return err == target
	}
	isComparable := reflect.TypeOf(target).Comparable()
	for {
		if isComparable && err == target {
			return true
		}
		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
			return true
		}
		if err = Unwrap(err); err == nil {
			return false
		}
	}
}
Is reports whether any error in err's chain matches target.

The chain consists of err itself followed by the sequence of errors obtained by repeatedly calling Unwrap.

An error is considered to match a target if it is equal to that target or if it implements a method
Is(error) bool such that Is(target) returns true.
package eris
import (
	"fmt"
	"io"
	"reflect"
)
func New(msg string) error {
	stack := callers(3)  
	return &rootError{
		global: stack.isGlobal(),
		msg:    msg,
		stack:  stack,
	}
}
func Errorf(format string, args ...interface{}) error {
	stack := callers(3)
	return &rootError{
		global: stack.isGlobal(),
		msg:    fmt.Sprintf(format, args...),
		stack:  stack,
	}
}
func Wrap(err error, msg string) error {
	return wrap(err, fmt.Sprint(msg))
}
func Wrapf(err error, format string, args ...interface{}) error {
	return wrap(err, fmt.Sprintf(format, args...))
}
func wrap(err error, msg string) error {
	if err == nil {
		return nil
	}
	stack := callers(4)
	frame := caller(3)
	switch e := err.(type) {
	case *rootError:
		if e.global {
			err = &rootError{
				global: e.global,
				msg:    e.msg,
				stack:  stack,
			}
		} else {
			e.stack.insertPC(*stack)
		}
	case *wrapError:
		if root, ok := Cause(err).(*rootError); ok {
			root.stack.insertPC(*stack)
		}
	default:
		return &rootError{
			msg:   msg,
			ext:   e,
			stack: stack,
		}
	}
	return &wrapError{
		msg:   msg,
		err:   err,
		frame: frame,
	}
}
func Unwrap(err error) error {
	u, ok := err.(interface {
		Unwrap() error
	})
	if !ok {
		return nil
	}
	return u.Unwrap()
}