Skip to content

Commit 0efb18e

Browse files
committed
增加 args 携带方法
1 parent 19bdd33 commit 0efb18e

7 files changed

Lines changed: 76 additions & 27 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.1
4+
5+
> 此版本发布于 2024-08-12
6+
7+
* 增加 args 携带方法
8+
39
### v0.7.0
410

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

README.en.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ func main() {
4343
fmt.Println(code, message)
4444

4545
// Also, we provide some useful information carrier for you.
46-
// For examples, you can carry an error or caller information.
47-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller()
46+
// 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")
4848
fmt.Println(err)
4949
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
5050

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ func main() {
4343
fmt.Println(code, message)
4444

4545
// Also, we provide some useful information carrier for you.
46-
// For examples, you can carry an error or caller information.
47-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller()
46+
// 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")
4848
fmt.Println(err)
4949
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
5050

_examples/basic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ func main() {
2929
fmt.Println(code, message)
3030

3131
// Also, we provide some useful information carrier for you.
32-
// For examples, you can carry an error or caller information.
33-
err = errors.Wrap(9999, "io timeout").With(io.EOF).WithCaller()
32+
// 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")
3434
fmt.Println(err)
3535
fmt.Println(errors.CodeMessage(err, 6666, "default message"))
3636

_icons/coverage.svg

Lines changed: 2 additions & 2 deletions
Loading

wrap.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ package errors
66

77
import (
88
"bytes"
9+
"encoding/json"
910
"fmt"
10-
"strings"
11+
)
12+
13+
const (
14+
keyBad = "errors.bad_key"
15+
keyCaller = "errors.caller"
16+
keyCallers = "errors.callers"
1117
)
1218

1319
type Error struct {
1420
code int32
1521
message string
1622
cause error
17-
caller string
23+
args map[string]any
1824
}
1925

2026
// Wrap returns *Error with code and message formatted with args.
@@ -31,20 +37,30 @@ func Wrap(code int32, message string, args ...any) *Error {
3137
return err
3238
}
3339

40+
// With carries the cause err for *Error.
3441
func (e *Error) With(err error) *Error {
3542
e.cause = err
3643
return e
3744
}
3845

39-
func (e *Error) WithCaller() *Error {
40-
e.caller = Caller()
46+
// WithArgs carries some args for *Error.
47+
func (e *Error) WithArgs(key string, value any) *Error {
48+
if e.args == nil {
49+
e.args = make(map[string]any, 4)
50+
}
51+
52+
e.args[key] = value
4153
return e
4254
}
4355

56+
// WithCaller carries the top caller for *Error.
57+
func (e *Error) WithCaller() *Error {
58+
return e.WithArgs(keyCaller, Caller())
59+
}
60+
61+
// WithCallers carries all callers for *Error.
4462
func (e *Error) WithCallers() *Error {
45-
callers := Callers()
46-
e.caller = strings.Join(callers, " ¦ ")
47-
return e
63+
return e.WithArgs(keyCallers, Callers())
4864
}
4965

5066
// Code returns the code of *Error.
@@ -67,13 +83,24 @@ func (e *Error) Error() string {
6783
return e.String()
6884
}
6985

86+
func (e *Error) marshalArgs() []byte {
87+
args, err := json.Marshal(e.args)
88+
if err == nil {
89+
return args
90+
}
91+
92+
argsString := fmt.Sprintf(`{"args":"%+v","marshal_error":"%+v"}`, e.args, err)
93+
return []byte(argsString)
94+
}
95+
7096
// String returns *Error as string.
7197
func (e *Error) String() string {
7298
var buff bytes.Buffer
7399
fmt.Fprintf(&buff, "%d: %s", e.code, e.message)
74100

75-
if e.caller != "" {
76-
fmt.Fprintf(&buff, " [%s]", e.caller)
101+
if len(e.args) > 0 {
102+
buff.WriteByte(' ')
103+
buff.Write(e.marshalArgs())
77104
}
78105

79106
if e.cause != nil {

wrap_test.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,24 @@ import (
1212
// go test -v -cover -count=1 -test.cpu=1 -run=^TestWrap$
1313
func TestWrap(t *testing.T) {
1414
testCases := []struct {
15-
code int32
16-
message string
15+
code int32
16+
message string
17+
args []any
18+
wantCode int32
19+
wantMessage string
1720
}{
18-
{code: -1000, message: "io timeout"},
19-
{code: 1000, message: "need login"},
21+
{code: -1000, message: "io timeout", args: nil, wantCode: -1000, wantMessage: "io timeout"},
22+
{code: 1000, message: "need login", args: nil, wantCode: 1000, wantMessage: "need login"},
23+
{code: 2000, message: "with args %d %s %+v", args: []any{1, "x", true}, wantCode: 2000, wantMessage: "with args 1 x true"},
2024
}
2125

2226
for _, testCase := range testCases {
23-
err := Wrap(testCase.code, testCase.message)
24-
if err.Code() != testCase.code {
27+
err := Wrap(testCase.code, testCase.message, testCase.args...)
28+
if err.Code() != testCase.wantCode {
2529
t.Errorf("err.Code() %d != testCase.code %d", err.Code(), testCase.code)
2630
}
2731

28-
if err.Message() != testCase.message {
32+
if err.Message() != testCase.wantMessage {
2933
t.Errorf("err.Message() %s != testCase.code %s", err.Message(), testCase.message)
3034
}
3135

@@ -43,7 +47,7 @@ func TestWrapWith(t *testing.T) {
4347
cause error
4448
}{
4549
{code: -1000, message: "eof", cause: io.EOF},
46-
{code: 1000, message: "need login"},
50+
{code: 1000, message: "need login", cause: nil},
4751
}
4852

4953
for _, testCase := range testCases {
@@ -68,14 +72,26 @@ func TestErrorError(t *testing.T) {
6872
code int32
6973
message string
7074
cause error
75+
args map[string]any
7176
errorString string
7277
}{
73-
{code: -1000, message: "eof", cause: io.EOF, errorString: "-1000: eof (EOF)"},
74-
{code: 1000, message: "need login", errorString: "1000: need login"},
78+
{code: -1000, message: "eof", cause: io.EOF, args: nil, errorString: "-1000: eof (EOF)"},
79+
{code: -1000, message: "eof", cause: io.EOF, args: map[string]any{"x": 666, "y": "300ms", "z": false}, errorString: "-1000: eof {\"x\":666,\"y\":\"300ms\",\"z\":false} (EOF)"},
80+
{code: 1000, message: "need login", args: nil, errorString: "1000: need login"},
81+
{code: 1000, message: "need login", args: map[string]any{"x": 123, "y": "100ms", "z": true}, errorString: "1000: need login {\"x\":123,\"y\":\"100ms\",\"z\":true}"},
7582
}
7683

7784
for _, testCase := range testCases {
7885
err := Wrap(testCase.code, testCase.message).With(testCase.cause)
86+
87+
for key, value := range testCase.args {
88+
err = err.WithArgs(key, value)
89+
}
90+
91+
if len(err.args) != len(testCase.args) {
92+
t.Errorf("len(err.args) %d != len(testCase.args) %d", len(err.args), len(testCase.args))
93+
}
94+
7995
if err.Error() != testCase.errorString {
8096
t.Errorf("err.Error() %s != testCase.errorString %s", err.Error(), testCase.errorString)
8197
}

0 commit comments

Comments
 (0)