func (e *werror) SafeParams() map[string]interface{} {
	safe, _ := ParamsFromError(e.cause)
	for k, v := range e.params {
		if v.safe {
			if _, exists := safe[k]; !exists {
				safe[k] = v.value
			}
		}
	}
	return safe
}
SafeParams returns params from this error and any underlying causes. If the error and its causes
contain multiple values for the same key, the most specific (deepest) value will be returned.
package werror
import (
	"context"
	"fmt"
	wparams "github.com/palantir/witchcraft-go-params"
)
var _ Werror = (*werror)(nil)
func Error(msg string, params ...Param) error {
	return newWerror(msg, nil, params...)
}
func ErrorWithContextParams(ctx context.Context, msg string, params ...Param) error {
	safe, unsafe := wparams.SafeAndUnsafeParamsFromContext(ctx)
	fullParams := []Param{
		SafeParams(safe),
		UnsafeParams(unsafe),
	}
	fullParams = append(fullParams, params...)
	return newWerror(msg, nil, fullParams...)
}
func Wrap(err error, msg string, params ...Param) error {
	if err == nil {
		return nil
	}
	return newWerror(msg, err, params...)
}
func WrapWithContextParams(ctx context.Context, err error, msg string, params ...Param) error {
	if err == nil {
		return nil
	}
	safe, unsafe := wparams.SafeAndUnsafeParamsFromContext(ctx)
	fullParams := []Param{
		SafeParams(safe),
		UnsafeParams(unsafe),
	}
	fullParams = append(fullParams, params...)
	return newWerror(msg, err, fullParams...)
}
func Convert(err error) error {
	if err == nil {
		return err
	}
	switch err.(type) {
	case Werror:
		return err
	default:
		return newWerror("", err)
	}
}
func RootCause(err error) error {
	for {
		causer, ok := err.(Causer)
		if !ok {
			return err
		}
		cause := causer.Cause()
		if cause == nil {
			return err
		}
		err = cause
	}
}
func ParamsFromError(err error) (safeParams map[string]interface{}, unsafeParams map[string]interface{}) {
	safeParams = make(map[string]interface{})
	unsafeParams = make(map[string]interface{})
	if err != nil {
		visitErrorParams(err, func(k string, v interface{}, safe bool) {
			if safe {
				safeParams[k] = v
			} else {
				unsafeParams[k] = v
			}
		})
	}
	return safeParams, unsafeParams
}
func ParamFromError(err error, key string) (value interface{}, safe bool) {
	visitErrorParams(err, func(k string, v interface{}, s bool) {
		if k == key {
			value = v
			safe = s
		}
	})
	return value, safe
}
func visitErrorParams(err error, visitor func(k string, v interface{}, safe bool)) {
	allErrs := []error{err}
	for currErr := err; ; {
		causer, ok := currErr.(Causer)
		if !ok || causer.Cause() == nil {
			break
		}
		allErrs = append(allErrs, causer.Cause())
		currErr = causer.Cause()
	}
	for _, currErr := range allErrs {
		if ps, ok := currErr.(wparams.ParamStorer); ok {
			for k, v := range ps.SafeParams() {
				visitor(k, v, true)
			}
			for k, v := range ps.UnsafeParams() {
				visitor(k, v, false)
			}
		}
	}
}
type Werror interface {
	error
	fmt.Formatter
	Causer
	StackTracer
	wparams.ParamStorer
	Message() string
}
type werror struct {
	message string
	cause   error
	stack   StackTrace
	params  map[string]paramValue
}
type paramValue struct {
	safe  bool
	value interface{}
}
type Causer interface {
	Cause() error
}
func newWerror(message string, cause error, params ...Param) error {
	we := &werror{
		message: message,
		cause:   cause,
		stack:   NewStackTraceWithSkip(1),
		params:  make(map[string]paramValue),
	}
	for _, p := range params {
		p.apply(we)
	}
	return we
}
func (e *werror) Error() string {
	if e.cause == nil {
		return e.message
	}
	if e.message == "" {
		return e.cause.Error()
	}
	return e.message + ": " + e.cause.Error()
}
func (e *werror) Cause() error {
	return e.cause
}
func (e *werror) Unwrap() error {
	return e.cause
}
func (e *werror) StackTrace() StackTrace {
	return e.stack
}
func (e *werror) Message() string {
	return e.message
}