func PublicAttributes(err ...error) map[string]interface{} {
	attributes := make(map[string]interface{})
	for _, err := range err {
		if err, ok := err.(publicAttributer); ok {
			for k, v := range err.PublicAttributes() {
				if _, ok := attributes[k]; !ok {
					attributes[k] = v
				}
			}
		}
	}
	return attributes
}
PublicAttributes returns the public attributes of the errors, if they implement PublicAttributes().
If more than one error is passed, subsequent error attributes will be added if not set.
package errors
import (
	"fmt"
	"reflect"
)
type attributer interface {
	Attributes() map[string]interface{}
}
type publicAttributer interface {
	PublicAttributes() map[string]interface{}
}
var errOddKV = DefineInvalidArgument("odd_kv", "Odd number of key-value elements")
func supported(v interface{}) interface{} {
	if v == nil {
		return "<nil>"
	}
	rv := reflect.Indirect(reflect.ValueOf(v))
	switch rv.Type().Kind() {
	case reflect.Int:
		return int(rv.Int())
	case reflect.Float64:
		return rv.Float()
	case reflect.String:
		return rv.String()
	default:
		return fmt.Sprintf("%v", v)
	}
}
func kvToMap(kv ...interface{}) (map[string]interface{}, error) {
	if len(kv)%2 != 0 {
		return nil, errOddKV.New()
	}
	m := make(map[string]interface{}, len(kv)/2)
	var key string
	for i, node := range kv {
		if i%2 == 0 {
			key = fmt.Sprintf("%v", node)
		} else {
			m[key] = node
		}
	}
	return m, nil
}
func (e *Error) mergeAttributes(kv ...interface{}) {
	if len(kv) == 0 {
		return
	}
	attributes, err := kvToMap(kv...)
	if err != nil {
		panic(err)
	}
	if e.attributes != nil {
		for k, v := range e.attributes {
			if _, ok := attributes[k]; !ok {
				attributes[k] = v
			}
		}
	}
	e.attributes = attributes
	for k, v := range e.attributes {
		for _, arg := range e.messageFormatArguments {
			if k == arg {
				e.attributes[k] = supported(v)
			}
		}
	}
	if e.stack == nil {
		e.stack = callers(4)
	}
	e.clearGRPCStatus()
}
func (e *Error) WithAttributes(kv ...interface{}) *Error {
	if e == nil {
		return e
	}
	deriv := *e
	deriv.mergeAttributes(kv...)
	return &deriv
}
func (d *Definition) WithAttributes(kv ...interface{}) *Error {
	if d == nil {
		return nil
	}
	e := build(d, 0)  
	e.mergeAttributes(kv...)
	return e
}
func (e *Error) Attributes() map[string]interface{} {
	if e == nil {
		return nil
	}
	return e.attributes
}
func (e *Error) PublicAttributes() map[string]interface{} {
	if e == nil {
		return nil
	}
	if len(e.attributes) == 0 {
		return nil
	}
	publicAttributes := make(map[string]interface{}, len(e.attributes))
nextAttr:
	for k, v := range e.attributes {
		for _, public := range e.publicAttributes {
			if k == public {
				publicAttributes[k] = v
				continue nextAttr
			}
		}
	}
	if len(publicAttributes) == 0 {
		return nil
	}
	return publicAttributes
}
func (d *Definition) Attributes() map[string]interface{} { return nil }
func (d *Definition) PublicAttributes() map[string]interface{} { return nil }
func Attributes(err ...error) map[string]interface{} {
	attributes := make(map[string]interface{})
	for _, err := range err {
		if err, ok := err.(attributer); ok {
			for k, v := range err.Attributes() {
				if _, ok := attributes[k]; !ok {
					attributes[k] = v
				}
			}
		}
	}
	return attributes
}