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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
|
package main
import (
"fmt"
"time"
)
// 1. 实现error接口的自定义错误
type ValidationError struct {
Field string
Value interface{}
Message string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("验证错误 [%s]: %s (值: %v)", e.Field, e.Message, e.Value)
}
// 2. 带错误码的错误类型
type APIError struct {
Code int
Message string
Details map[string]interface{}
}
func (e APIError) Error() string {
return fmt.Sprintf("API错误 [%d]: %s", e.Code, e.Message)
}
func (e APIError) GetCode() int {
return e.Code
}
func (e APIError) GetDetails() map[string]interface{} {
return e.Details
}
// 3. 临时错误接口
type TemporaryError interface {
error
Temporary() bool
}
type NetworkError struct {
Op string
Addr string
Err error
Temporary bool
}
func (e NetworkError) Error() string {
return fmt.Sprintf("网络错误 [%s %s]: %v", e.Op, e.Addr, e.Err)
}
func (e NetworkError) Temporary() bool {
return e.Temporary
}
func (e NetworkError) Unwrap() error {
return e.Err
}
// 4. 错误分类
type ErrorType int
const (
ErrorTypeValidation ErrorType = iota
ErrorTypeNetwork
ErrorTypeDatabase
ErrorTypePermission
ErrorTypeNotFound
)
type ClassifiedError struct {
Type ErrorType
Message string
Cause error
}
func (e ClassifiedError) Error() string {
typeNames := map[ErrorType]string{
ErrorTypeValidation: "验证错误",
ErrorTypeNetwork: "网络错误",
ErrorTypeDatabase: "数据库错误",
ErrorTypePermission: "权限错误",
ErrorTypeNotFound: "未找到",
}
typeName := typeNames[e.Type]
if e.Cause != nil {
return fmt.Sprintf("%s: %s (原因: %v)", typeName, e.Message, e.Cause)
}
return fmt.Sprintf("%s: %s", typeName, e.Message)
}
func (e ClassifiedError) Unwrap() error {
return e.Cause
}
// 5. 使用自定义错误的函数
func validateUser(name string, age int, email string) error {
if name == "" {
return ValidationError{
Field: "name",
Value: name,
Message: "姓名不能为空",
}
}
if age < 0 || age > 150 {
return ValidationError{
Field: "age",
Value: age,
Message: "年龄必须在0-150之间",
}
}
if email == "" {
return ValidationError{
Field: "email",
Value: email,
Message: "邮箱不能为空",
}
}
return nil
}
func callAPI(endpoint string) error {
// 模拟API调用
switch endpoint {
case "/users":
return nil
case "/forbidden":
return APIError{
Code: 403,
Message: "访问被禁止",
Details: map[string]interface{}{
"endpoint": endpoint,
"time": time.Now(),
},
}
case "/notfound":
return APIError{
Code: 404,
Message: "资源未找到",
Details: map[string]interface{}{
"endpoint": endpoint,
},
}
default:
return APIError{
Code: 500,
Message: "内部服务器错误",
Details: map[string]interface{}{
"endpoint": endpoint,
"error": "未知端点",
},
}
}
}
func connectToServer(addr string) error {
// 模拟网络连接
if addr == "unreachable.com" {
return NetworkError{
Op: "connect",
Addr: addr,
Err: fmt.Errorf("连接超时"),
Temporary: true,
}
}
if addr == "invalid.com" {
return NetworkError{
Op: "connect",
Addr: addr,
Err: fmt.Errorf("无效地址"),
Temporary: false,
}
}
return nil
}
func main() {
// 1. 自定义验证错误
fmt.Println("=== 自定义验证错误 ===")
users := []struct {
name string
age int
email string
}{
{"张三", 25, "zhangsan@example.com"},
{"", 30, "test@example.com"},
{"李四", -5, "lisi@example.com"},
{"王五", 25, ""},
}
for _, user := range users {
if err := validateUser(user.name, user.age, user.email); err != nil {
fmt.Printf("用户验证失败: %v\n", err)
// 类型断言获取详细信息
if validationErr, ok := err.(ValidationError); ok {
fmt.Printf(" 字段: %s, 值: %v\n", validationErr.Field, validationErr.Value)
}
} else {
fmt.Printf("用户 %s 验证通过\n", user.name)
}
}
// 2. API错误处理
fmt.Println("\n=== API错误处理 ===")
endpoints := []string{"/users", "/forbidden", "/notfound", "/unknown"}
for _, endpoint := range endpoints {
if err := callAPI(endpoint); err != nil {
fmt.Printf("API调用失败: %v\n", err)
// 类型断言获取错误码和详情
if apiErr, ok := err.(APIError); ok {
fmt.Printf(" 错误码: %d\n", apiErr.GetCode())
fmt.Printf(" 详情: %v\n", apiErr.GetDetails())
}
} else {
fmt.Printf("API调用成功: %s\n", endpoint)
}
}
// 3. 网络错误和临时错误
fmt.Println("\n=== 网络错误处理 ===")
addresses := []string{"google.com", "unreachable.com", "invalid.com"}
for _, addr := range addresses {
if err := connectToServer(addr); err != nil {
fmt.Printf("连接失败: %v\n", err)
// 检查是否是临时错误
if tempErr, ok := err.(TemporaryError); ok {
if tempErr.Temporary() {
fmt.Printf(" 这是临时错误,可以重试\n")
} else {
fmt.Printf(" 这是永久错误,不应重试\n")
}
}
} else {
fmt.Printf("连接成功: %s\n", addr)
}
}
// 4. 错误分类
fmt.Println("\n=== 错误分类 ===")
classifiedErrors := []ClassifiedError{
{
Type: ErrorTypeValidation,
Message: "输入数据无效",
},
{
Type: ErrorTypeNetwork,
Message: "网络连接失败",
Cause: fmt.Errorf("连接超时"),
},
{
Type: ErrorTypeDatabase,
Message: "数据库查询失败",
Cause: fmt.Errorf("表不存在"),
},
}
for _, err := range classifiedErrors {
fmt.Printf("分类错误: %v\n", err)
}
}
|