-
Notifications
You must be signed in to change notification settings - Fork 0
/
error_withcode_test.go
149 lines (120 loc) · 3.77 KB
/
error_withcode_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package errors
import (
"fmt"
"testing"
)
const (
// ErrUserNotFound - 404: User not found.
ErrUserNotFound int = iota + 110001
// ErrUserAlreadyExist - 400: User encode error.
ErrUserEncode
)
// ErrCode implements `github.com/cr-mao/errors`.Coder interface.
type ErrCode struct {
// C refers to the code of the ErrCode.
C int
// HTTP status that should be used for the associated error code.
HTTP int
// External (user) facing error text.
Ext string
// Ref specify the reference document.
Ref string
}
// Code returns the integer code of ErrCode.
func (coder ErrCode) Code() int {
return coder.C
}
// String implements stringer. String returns the external error message,
// if any.
func (coder ErrCode) String() string {
return coder.Ext
}
// Reference returns the reference document.
func (coder ErrCode) Reference() string {
return coder.Ref
}
// HTTPStatus returns the associated HTTP status code, if any. Otherwise,
// returns 200.
func (coder ErrCode) HTTPStatus() int {
if coder.HTTP == 0 {
return 500
}
return coder.HTTP
}
func register(code int, httpStatus int, message string, refs ...string) {
if httpStatus != 200 && httpStatus != 400 && httpStatus != 401 && httpStatus != 403 && httpStatus != 404 && httpStatus != 500 {
panic("http code not in `200, 400, 401, 403, 404, 500`")
}
var reference string
if len(refs) > 0 {
reference = refs[0]
}
coder := &ErrCode{
C: code,
HTTP: httpStatus,
Ext: message,
Ref: reference,
}
MustRegister(coder)
}
func TestWithCode(t *testing.T) {
//注册code
register(ErrUserNotFound, 400, "user not found")
register(ErrUserEncode, 400, "user encode error")
err := WithCode(ErrUserNotFound, "user %s not found.", "cr-mao")
if err != nil {
fmt.Println(err.Error()) // user not found
}
}
func TestWithCodeDetail(t *testing.T) {
//注册code
register(ErrUserNotFound, 400, "user not found")
register(ErrUserEncode, 400, "user encode error")
if err := bindUser(); err != nil {
// %s: Returns the user-safe error string mapped to the error code or the error message if none is specified.
fmt.Println("====================> s <====================")
fmt.Printf("%s\n\n", err)
// %v: Alias for %s.
fmt.Println("====================> v <====================")
fmt.Printf("%v\n\n", err)
// %-v: Output caller details, useful for troubleshooting.
fmt.Println("====================> -v <====================")
fmt.Printf("%-v\n\n", err)
// %+v: Output full error stack details, useful for debugging.
fmt.Println("====================> +v <====================")
fmt.Printf("%+v\n\n", err)
// %#-v: Output caller details, useful for troubleshooting with JSON formatted output.
fmt.Println("====================> #-v <====================")
fmt.Printf("%#-v\n\n", err)
// %#+v: Output full error stack details, useful for debugging with JSON formatted output.
fmt.Println("====================> #+v <====================")
fmt.Printf("%#+v\n\n", err)
// do some business process based on the error type
if IsCode(err, ErrUserEncode) {
fmt.Println("this is a ErrEncodingFailed error")
}
if IsCode(err, ErrUserNotFound) {
fmt.Println("this is a ErrDatabase error")
}
// we can also find the cause error
fmt.Println(Cause(err))
}
}
func bindUser() error {
if err := getUser(); err != nil {
// Step3: Wrap the error with a new error message and a new error code if needed.
return WrapC(err, ErrUserEncode, "encoding user %s failed.", "cr-mao")
}
return nil
}
func getUser() error {
if err := queryDatabase(); err != nil {
// Step2: Wrap the error with a new error message.
return Wrap(err, "get user failed.")
}
return nil
}
func queryDatabase() error {
// Step1. Create error with specified error code.
return WithCode(ErrUserNotFound, "user %s not found.", "cr-mao")
}