diff --git a/merr/kv_test.go b/merr/kv_test.go index 28a8b9b..dc1f107 100644 --- a/merr/kv_test.go +++ b/merr/kv_test.go @@ -15,12 +15,13 @@ func TestKV(t *T) { massert.Len(KV(nil).KV(), 0), )) - er := New("foo") + er := New("foo", "bar", "baz") kv := KV(er).KV() massert.Fatal(t, massert.Comment( massert.All( - massert.Len(kv, 2), + massert.Len(kv, 3), massert.Equal("foo", kv["err"]), + massert.Equal("baz", kv["bar"]), massert.Equal(true, strings.HasPrefix(kv["errSrc"].(string), "merr/kv_test.go:")), ), @@ -36,8 +37,9 @@ func TestKV(t *T) { kv = KV(er).KV() massert.Fatal(t, massert.Comment( massert.All( - massert.Len(kv, 3), + massert.Len(kv, 4), massert.Equal("foo", kv["err"]), + massert.Equal("baz", kv["bar"]), massert.Equal(true, strings.HasPrefix(kv["errSrc"].(string), "merr/kv_test.go:")), massert.Equal("1", kv["k"]), @@ -49,8 +51,9 @@ func TestKV(t *T) { kv = KV(er).KV() massert.Fatal(t, massert.Comment( massert.All( - massert.Len(kv, 4), + massert.Len(kv, 5), massert.Equal("foo", kv["err"]), + massert.Equal("baz", kv["bar"]), massert.Equal(true, strings.HasPrefix(kv["errSrc"].(string), "merr/kv_test.go:")), massert.Equal("1", kv["merr.A(k)"]), @@ -63,8 +66,9 @@ func TestKV(t *T) { kv = KV(er).KV() massert.Fatal(t, massert.Comment( massert.All( - massert.Len(kv, 5), + massert.Len(kv, 6), massert.Equal("foo", kv["err"]), + massert.Equal("baz", kv["bar"]), massert.Equal(true, strings.HasPrefix(kv["errSrc"].(string), "merr/kv_test.go:")), massert.Equal("1", kv["merr.A(k)"]), diff --git a/merr/merr.go b/merr/merr.go index f162501..f585e21 100644 --- a/merr/merr.go +++ b/merr/merr.go @@ -83,13 +83,25 @@ func Wrap(e error) error { // New returns a new error with the given string as its error string. New // automatically wraps the error in merr's inner type, which embeds information // like the stack trace. -func New(str string) error { - return wrap(errors.New(str), false, 1) -} - -// Errorf is like New, but allows for formatting of the string. -func Errorf(str string, args ...interface{}) error { - return wrap(fmt.Errorf(str, args...), false, 1) +// +// For convenience, visible key/values may be passed into New at this point. For +// example, the following two are equivalent: +// +// merr.WithValue(merr.New("foo"), "bar", "baz", true) +// merr.New("foo", "bar", "baz") +// +func New(str string, kvs ...interface{}) error { + if len(kvs)%2 != 0 { + panic("key passed in without corresponding value") + } + err := wrap(errors.New(str), false, 1) + for i := 0; i < len(kvs); i += 2 { + err.attr[kvs[i]] = val{ + visible: true, + val: kvs[i+1], + } + } + return err } func (er *err) visibleAttrs() [][2]string {