Skip to content

Commit 5451bea

Browse files
committed
feat: cosy error struct
1 parent ce12cf9 commit 5451bea

File tree

3 files changed

+129
-19
lines changed

3 files changed

+129
-19
lines changed

docs/.vitepress/config.mts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ export default defineConfig(({mode}) => {
7171
{text: '接口参考', link: '/validator/validator'},
7272
]
7373
},
74+
{
75+
text: '错误处理',
76+
items: [
77+
{text: '接口参考', link: '/error-handler'},
78+
]
79+
},
7480
{
7581
text: 'Sonyflake',
7682
items: [

docs/error-handler/index.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# 错误处理
2+
3+
`v1.10.0` 中,我们引入了新的错误类型 `cosy.Error` 并且实现了 `go error` 的接口。
4+
```go
5+
type Error struct {
6+
Code int32 `json:"code"`
7+
Message string `json:"message"`
8+
}
9+
10+
func (e *Error) Error() string {
11+
return e.Message
12+
}
13+
```
14+
15+
你可以在任何地方使用 NewError 来创建一个 `cosy.Error` 对象。
16+
17+
```go
18+
func NewError(code int32, message string) *Error
19+
```
20+
21+
我们建议将错误信息集中管理,例如:
22+
23+
```go
24+
package user
25+
26+
import (
27+
"github.com/uozi-tech/cosy"
28+
)
29+
30+
var (
31+
ErrMaxAttempts = cosy.NewError(4291, "Too many requests")
32+
ErrPasswordIncorrect = cosy.NewError(4031, "Password incorrect")
33+
ErrUserBanned = cosy.NewError(4033, "User banned")
34+
ErrUserWaitForValidation = cosy.NewError(4032, "The user is waiting for validation")
35+
)
36+
```
37+
38+
接下来,您只需要在业务层调用 `cosy.ErrHandler(c, err)`
39+
40+
```go
41+
func ErrorHandler(c *gin.Context, err error)
42+
```
43+
44+
在 `cosy.ErrHandler` 中,我们会做如下逻辑处理:
45+
46+
1. 如果错误是一个 `gorm.ErrRecordNotFound`,则返回
47+
```json
48+
{
49+
"code": 404,
50+
"message": "record not found"
51+
}
52+
```
53+
54+
2. 如果错误是一个 `cosy.Error`,则会返回
55+
```
56+
{
57+
"code": 错误码,
58+
"message": 错误信息
59+
}
60+
```
61+
62+
3. 其他情况(通常情况是未知错误、或者是由于设计缺陷引起)
63+
64+
`ServerSettings.RunMode``debug`, `testing` 的情况下,函数会输出:
65+
```json
66+
{
67+
"message": "未知的错误信息"
68+
}
69+
```
70+
71+
`ServerSettings.RunMode``release` 的情况下,函数会统一输出,如需查看实际错误,请检查控制台日志。
72+
```json
73+
{
74+
"message": "Server error"
75+
}
76+
```

error.go

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,63 @@ import (
44
"errors"
55
"github.com/gin-gonic/gin"
66
"github.com/uozi-tech/cosy/logger"
7+
"github.com/uozi-tech/cosy/settings"
78
"go.uber.org/zap"
89
"gorm.io/gorm"
910
"net/http"
1011
)
1112

12-
func errHandler(c *gin.Context, err error) {
13-
logger.GetLogger().WithOptions(zap.AddCallerSkip(1)).Errorln(err)
14-
if errors.Is(err, gorm.ErrRecordNotFound) {
15-
c.JSON(http.StatusNotFound, gin.H{
16-
"message": err.Error(),
17-
})
18-
return
13+
type Error struct {
14+
Code int32 `json:"code"`
15+
Message string `json:"message"`
16+
}
17+
18+
func (e *Error) Error() string {
19+
return e.Message
20+
}
21+
22+
func NewError(code int32, message string) error {
23+
return &Error{
24+
Code: code,
25+
Message: message,
1926
}
20-
c.JSON(http.StatusInternalServerError, gin.H{
21-
"message": err.Error(),
22-
})
2327
}
2428

25-
func ErrHandler(c *gin.Context, err error) {
26-
logger.GetLogger().Errorln(err)
29+
// errorResp error response
30+
func errorResp(c *gin.Context, err error) {
31+
var cErr *Error
32+
switch {
33+
case errors.Is(err, gorm.ErrRecordNotFound):
34+
c.JSON(http.StatusNotFound, &Error{
35+
Code: http.StatusNotFound,
36+
Message: gorm.ErrRecordNotFound.Error(),
37+
})
38+
case errors.As(err, &cErr):
39+
c.JSON(http.StatusInternalServerError, cErr)
40+
default:
41+
if settings.ServerSettings.RunMode != gin.ReleaseMode {
42+
c.JSON(http.StatusInternalServerError, &Error{
43+
Code: http.StatusInternalServerError,
44+
Message: err.Error(),
45+
})
46+
return
47+
}
2748

28-
if errors.Is(err, gorm.ErrRecordNotFound) {
29-
c.JSON(http.StatusNotFound, gin.H{
30-
"message": err.Error(),
49+
c.JSON(http.StatusInternalServerError, &Error{
50+
Code: http.StatusInternalServerError,
51+
Message: "Server Error",
3152
})
32-
return
3353
}
54+
}
55+
56+
// errHandler error handler for internal use
57+
func errHandler(c *gin.Context, err error) {
58+
logger.GetLogger().WithOptions(zap.AddCallerSkip(1)).Errorln(err)
59+
errorResp(c, err)
60+
}
3461

35-
c.JSON(http.StatusInternalServerError, gin.H{
36-
"message": err.Error(),
37-
})
62+
// ErrHandler error handler for external use
63+
func ErrHandler(c *gin.Context, err error) {
64+
logger.GetLogger().Errorln(err)
65+
errorResp(c, err)
3866
}

0 commit comments

Comments
 (0)