Skip to content

Commit 10005a1

Browse files
committed
调整 WithArgs 方法,支持多参数传递
1 parent 0efb18e commit 10005a1

7 files changed

Lines changed: 121 additions & 8 deletions

File tree

HISTORY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## ✒ 历史版本的特性介绍 (Features in old versions)
22

3+
### v0.7.2
4+
5+
> 此版本发布于 2024-08-21
6+
7+
* 调整 WithArgs 方法,支持多参数传递
8+
39
### v0.7.1
410

511
> 此版本发布于 2024-08-12

README.en.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ func main() {
4444

4545
// Also, we provide some useful information carrier for you.
4646
// For examples, you can carry an error, caller information or some args.
47-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123).WithArgs("timeout", "200ms")
47+
// Remember args should be a field slice with string keys and any values.
48+
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123, "timeout", "200ms")
4849
fmt.Println(err)
4950
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
5051

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ func main() {
4444

4545
// Also, we provide some useful information carrier for you.
4646
// For examples, you can carry an error, caller information or some args.
47-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123).WithArgs("timeout", "200ms")
47+
// Remember args should be a field slice with string keys and any values.
48+
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123, "timeout", "200ms")
4849
fmt.Println(err)
4950
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
5051

_examples/basic.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ func main() {
3030

3131
// Also, we provide some useful information carrier for you.
3232
// For examples, you can carry an error, caller information or some args.
33-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123).WithArgs("timeout", "200ms")
33+
// Remember args should be a field slice with string keys and any values.
34+
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller().WithArgs("user_id", 123, "timeout", "200ms")
3435
fmt.Println(err)
3536
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
3637

_icons/coverage.svg

Lines changed: 2 additions & 2 deletions
Loading

wrap.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"bytes"
99
"encoding/json"
1010
"fmt"
11+
"strconv"
1112
)
1213

1314
const (
@@ -44,12 +45,36 @@ func (e *Error) With(err error) *Error {
4445
}
4546

4647
// WithArgs carries some args for *Error.
47-
func (e *Error) WithArgs(key string, value any) *Error {
48+
func (e *Error) WithArgs(args ...any) *Error {
4849
if e.args == nil {
4950
e.args = make(map[string]any, 4)
5051
}
5152

52-
e.args[key] = value
53+
badKeys := 0
54+
badKey := func() string {
55+
badKeys++
56+
return keyBad + "_" + strconv.Itoa(badKeys)
57+
}
58+
59+
for len(args) > 0 {
60+
// One last arg, tag it as bad key.
61+
if len(args) == 1 {
62+
e.args[badKey()] = args[0]
63+
break
64+
}
65+
66+
// len(kvs) >= 2, the key should be a string
67+
k, v := args[0], args[1]
68+
if ks, ok := k.(string); ok {
69+
e.args[ks] = v
70+
} else {
71+
e.args[badKey()] = k
72+
e.args[badKey()] = v
73+
}
74+
75+
args = args[2:]
76+
}
77+
5378
return e
5479
}
5580

@@ -73,11 +98,25 @@ func (e *Error) Message() string {
7398
return e.message
7499
}
75100

76-
// Unwrap unwraps *Error and returns its cause error.
101+
// Unwrap returns the cause of *Error.
77102
func (e *Error) Unwrap() error {
78103
return e.cause
79104
}
80105

106+
// Args returns the args of *Error.
107+
func (e *Error) Args() map[string]any {
108+
if e.args == nil {
109+
return nil
110+
}
111+
112+
args := make(map[string]any, len(e.args))
113+
for k, v := range e.args {
114+
args[k] = v
115+
}
116+
117+
return args
118+
}
119+
81120
// Error returns *Error as string.
82121
func (e *Error) Error() string {
83122
return e.String()

wrap_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,37 @@
55
package errors
66

77
import (
8+
"fmt"
89
"io"
910
"testing"
1011
)
1112

13+
func compareMaps(m1 map[string]any, m2 map[string]any) error {
14+
for k1, v1 := range m1 {
15+
v2, ok := m2[k1]
16+
if !ok {
17+
return fmt.Errorf("key %s not found in m2 %+v", k1, m2)
18+
}
19+
20+
if v1 != v2 {
21+
return fmt.Errorf("v1 %+v != v2 %+v", v1, v2)
22+
}
23+
}
24+
25+
for k2, v2 := range m2 {
26+
v1, ok := m1[k2]
27+
if !ok {
28+
return fmt.Errorf("key %s not found in m1 %+v", k2, m1)
29+
}
30+
31+
if v1 != v2 {
32+
return fmt.Errorf("v1 %+v != v2 %+v", v1, v2)
33+
}
34+
}
35+
36+
return nil
37+
}
38+
1239
// go test -v -cover -count=1 -test.cpu=1 -run=^TestWrap$
1340
func TestWrap(t *testing.T) {
1441
testCases := []struct {
@@ -66,6 +93,44 @@ func TestWrapWith(t *testing.T) {
6693
}
6794
}
6895

96+
// go test -v -cover -count=1 -test.cpu=1 -run=^TestWrapWithArgs$
97+
func TestWrapWithArgs(t *testing.T) {
98+
testCases := []struct {
99+
code int32
100+
message string
101+
cause error
102+
args []any
103+
wantArgs map[string]any
104+
}{
105+
{code: -1000, message: "eof", cause: io.EOF, args: nil, wantArgs: nil},
106+
{code: 1000, message: "need login", cause: nil, args: nil, wantArgs: nil},
107+
{code: 1000, message: "need login", cause: nil, args: []any{io.EOF}, wantArgs: map[string]any{keyBad + "_1": io.EOF}},
108+
{code: -1000, message: "eof", cause: io.EOF, args: []any{1, true, 3.14, io.EOF}, wantArgs: map[string]any{keyBad + "_1": 1, keyBad + "_2": true, keyBad + "_3": 3.14, keyBad + "_4": io.EOF}},
109+
{code: -1000, message: "eof", cause: io.EOF, args: []any{1, true, 3.14, "abc"}, wantArgs: map[string]any{keyBad + "_1": 1, keyBad + "_2": true, keyBad + "_3": 3.14, keyBad + "_4": "abc"}},
110+
{code: 1000, message: "need login", cause: io.EOF, args: []any{"k1", 1, "k2", true, "k3", 3.14, "key", "abc"}, wantArgs: map[string]any{"k1": 1, "k2": true, "k3": 3.14, "key": "abc"}},
111+
}
112+
113+
for _, testCase := range testCases {
114+
err := Wrap(testCase.code, testCase.message).With(testCase.cause).WithArgs(testCase.args...)
115+
if err.Code() != testCase.code {
116+
t.Errorf("err.Code() %d != testCase.code %d", err.Code(), testCase.code)
117+
}
118+
119+
if err.Message() != testCase.message {
120+
t.Errorf("err.Message() %s != testCase.code %s", err.Message(), testCase.message)
121+
}
122+
123+
if err.Unwrap() != testCase.cause {
124+
t.Errorf("err.Unwrap() %+v != testCase.code %+v", err.Unwrap(), testCase.cause)
125+
}
126+
127+
args := err.Args()
128+
if merr := compareMaps(args, testCase.wantArgs); merr != nil {
129+
t.Error(merr)
130+
}
131+
}
132+
}
133+
69134
// go test -v -cover -count=1 -test.cpu=1 -run=^TestErrorError$
70135
func TestErrorError(t *testing.T) {
71136
testCases := []struct {

0 commit comments

Comments
 (0)