-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
164 lines (154 loc) · 4.6 KB
/
error.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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package common
import (
"fmt"
"log"
"net/http"
"github.com/getsentry/raven-go"
"github.com/gin-gonic/gin"
)
// FuncHandler 统一错误处理
// i 传入error,bool,int
// judge 触发正确值 非error环境下有效
// 如果触发了错误 return True
// Example:
// 1. common.FuncHandler(c, c.BindJSON(&x), nil, http.StatusBadRequest, 20301)
// == if(c.BindJSON(&x) != nil){
// c.JSON(http.StatusBadRequest, gin.H{
// "err_code": 20301,
// "message": common.Errors[20301],
// })
// }
// 2. common.FuncHandler(c, c.BindJSON(&x), nil, http.StatusBadRequest, 20301,fmt.Sprintf("BindJson fail with %v",x))
// == if(c.BindJSON(&x) != nil){
// log.Println(fmt.Sprintf("BindJson fail with %v",x))
// c.JSON(http.StatusBadRequest, gin.H{
// "err_code": 20301,
// "message": common.Errors[20301],
// })
// }
// 3. common.FuncHandler(c, isOdd(2), true, fmt.Sprintf("%d is even",2))
// == if(isOdd(2) != true){
// log.Println(fmt.Sprintf("%d is even",2))
// }
func FuncHandler(c *gin.Context, i interface{}, judge interface{}, option ...interface{}) bool {
generalReturn := buildErrorMeta(option)
errType := gin.ErrorTypePrivate
// http返回码和错误码齐全则为公开错误
if generalReturn.HTTPStatus != 0 || generalReturn.AppErrJSON.ErrCode != 0 {
errType = gin.ErrorTypePublic
}
switch i.(type) {
case nil:
return false
case error:
c.Error(i.(error)).SetMeta(generalReturn).SetType(errType)
return true
case bool:
if i.(bool) == judge.(bool) {
return false
}
if generalReturn.CustomMessage != "" {
c.Error(fmt.Errorf(generalReturn.CustomMessage)).SetMeta(generalReturn).SetType(errType)
} else if generalReturn.AppErrJSON.Message != "" {
c.Error(fmt.Errorf(generalReturn.AppErrJSON.Message)).SetMeta(generalReturn).SetType(errType)
} else {
c.Error(fmt.Errorf("no err")).SetMeta(generalReturn).SetType(errType)
}
return true
}
return true
}
func buildErrorMeta(option []interface{}) GeneralReturn {
var generalReturn GeneralReturn
for _, v := range option {
switch v.(type) {
case int:
// RFC 2616 HTTP Status Code 是3位数字代码
if v.(int) >= 1000 {
generalReturn.AppErrJSON.ErrCode = v.(int)
generalReturn.AppErrJSON.Message = Errors[v.(int)]
} else {
generalReturn.HTTPStatus = v.(int)
}
break
case string:
generalReturn.CustomMessage = v.(string)
break
}
}
return generalReturn
}
// GeneralReturn 通用码
type GeneralReturn struct {
CustomMessage string
HTTPStatus int
AppErrJSON appErrJSON
}
type appErrJSON struct {
ErrCode int `json:"err_code"`
Message string `json:"message"`
}
// ErrorHandling 错误处理中间件
func ErrorHandling() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
err := c.Errors.Last()
if err == nil {
return
}
// 转义
var metaData GeneralReturn
switch err.Meta.(type) {
case GeneralReturn:
metaData = err.Meta.(GeneralReturn)
default:
return
}
switch err.Type {
case gin.ErrorTypePublic:
// 公开错误 返回对应Http状态码和错误码
// 如果有自定义消息 写入日志
if metaData.CustomMessage != "" {
log.Println(metaData.CustomMessage)
raven.CaptureMessage(fmt.Sprintf("[custom] %v", metaData.CustomMessage), map[string]string{"type": "custom"})
}
c.JSON(metaData.HTTPStatus, metaData.AppErrJSON)
if metaData.AppErrJSON.ErrCode < 20000 {
raven.CaptureMessage(fmt.Sprintf("[%v] %v", metaData.AppErrJSON.ErrCode, metaData.AppErrJSON.Message), map[string]string{"type": "system"})
} else {
raven.CaptureMessage(fmt.Sprintf("[%v] %v", metaData.AppErrJSON.ErrCode, metaData.AppErrJSON.Message), map[string]string{"type": "application"})
}
return
case gin.ErrorTypePrivate:
// 如果有自定义消息 写入日志
if metaData.CustomMessage != "" {
log.Println(metaData.CustomMessage)
raven.CaptureMessage(fmt.Sprintf("[custom] %v", metaData.CustomMessage), map[string]string{"type": "custom"})
}
break
default:
c.JSON(http.StatusInternalServerError, gin.H{
"err_code": 10001,
"message": Errors[10001],
})
log.Println(c.ClientIP(), "SYSTEM ERROR")
raven.CaptureMessage(fmt.Sprintf("[%v] %v", 10001, Errors[10001]), map[string]string{"type": "system"})
return
}
}
}
// Errors 错误码
var Errors = map[int]string{
0: "OK",
// 系统级错误
10001: "System error",
10002: "Service unavailable",
10003: "Parameter error",
10004: "Parameter value invalid",
10005: "Missing required parameter",
10006: "Resource unavailable",
10007: "CSRF token mismatch",
10008: "This service is undergoing maintenance",
// 应用级错误
20000: "Application error",
}