pkg / errors

Simple error handling primitives
https://godoc.org/github.com/pkg/errors
BSD 2-Clause "Simplified" License
8.18k stars 692 forks source link

Proposal: adding custom fields to errors #153

Closed masterada closed 6 years ago

masterada commented 6 years ago

I suggest a WithFields() method that lets you add arbitrary data to your error object, that can later be fetched (even if it was added to a nested error). We use this with alternating key-values for adding useful information to our errors for logging them later.

Usage:

    err := errors.New("My error")
    err = errors.WithFields(err, MyCustomKeyValue{ key: "statusCode", value: 200})
    err = errors.WithFields(err, "any data", "can be added", 123)
    err = errors.WithStack(err)
    fields := errors.Fields(err)

Implementation:

type withFields struct {
    cause  error
    fields []interface{}
}

func WithFields(err error, fields ...interface{}) error {
    if len(fields) == 0 {
        return err
    }

    return &withFields{
        cause:  err,
        fields: fields,
    }
}

func (e *withFields) Error() string {
    return e.cause.Error()
}

func (e *withFields) Fields() []interface{} {
    return e.fields
}

func (e *withFields) Cause() error {
    return e.cause
}

func (e *withFields) Format(s fmt.State, verb rune) {
    switch verb {
    case 'v':
        if s.Flag('+') {
            fmt.Fprintf(s, "%+v\n", e.Cause())
            return
        }
        fallthrough
    case 's', 'q':
        io.WriteString(s, e.Error())
    }
}

func Fields(err error) []interface{} {
    type causer interface {
        Cause() error
    }

    type fielder interface {
        Fields() []interface{}
    }

    var fields []interface{}
    for err != nil {
        if fErr, ok := err.(fielder); ok {
            fields = append(fields, fErr.Fields()...)
        }

        cause, ok := err.(causer)
        if !ok {
            break
        }
        err = cause.Cause()
    }

    return fields
}
davecheney commented 6 years ago

Duplicate of #70

davecheney commented 6 years ago

Duplicate of #34

masterada commented 6 years ago

OK, sorry for duplicating, didn't check closed issues.