diff --git a/book/config/config.go b/book/config/config.go index 5d8fbae..7a59656 100644 --- a/book/config/config.go +++ b/book/config/config.go @@ -189,12 +189,12 @@ func (l *Log) Logger() *zerolog.Logger { // 带上中间信息Any // book/controller/book.go:60 root := zerolog.New(io.MultiWriter(writers...)).With().Timestamp().Any("服务", "book-api") - if l.CallerDeep > 0 { - zerolog.CallerMarshalFunc = l.CallerMarshalFunc + // 启用caller root = root.Caller() + // 配置自定义caller + zerolog.CallerMarshalFunc = l.CallerMarshalFunc } - // 带有这些上下文信息的Logger对象 提前出来,作为全局Logger对象,供全局使用 l.SetRoot(root.Logger().Level(l.Level)) } diff --git a/book/controller/book.go b/book/controller/book.go index 0fe7014..59dc0c5 100644 --- a/book/controller/book.go +++ b/book/controller/book.go @@ -2,9 +2,11 @@ package controller import ( "context" + "fmt" "github.com/rs/zerolog" "gitlab.com/go-course-project/go17/book/config" + "gitlab.com/go-course-project/go17/book/exception" "gitlab.com/go-course-project/go17/book/model" "gorm.io/gorm" ) @@ -42,8 +44,12 @@ func (c *BookController) GetBook(ctx context.Context, req *GetBookRequest) (*mod ins := &model.Book{} if err := c.db.WithContext(ctx).Where("isbn = ?", req.Isbn).Take(ins).Error; err != nil { - return nil, err + if err == gorm.ErrRecordNotFound { + return nil, exception.ErrNotFound("%d not found", req.Isbn) + } + return nil, fmt.Errorf("get book error, %s", err) } + return ins, nil } diff --git a/book/controller/book_test.go b/book/controller/book_test.go index d101180..33e5d52 100644 --- a/book/controller/book_test.go +++ b/book/controller/book_test.go @@ -5,14 +5,25 @@ import ( "testing" "gitlab.com/go-course-project/go17/book/controller" + "gitlab.com/go-course-project/go17/book/exception" "gitlab.com/go-course-project/go17/book/model" ) func TestGetBook(t *testing.T) { book := controller.NewBookController() ins, err := book.GetBook(context.Background(), &controller.GetBookRequest{ - Isbn: 5, + Isbn: 100, }) + + if err != nil && exception.IsNotFound(err) { + t.Log("is not found error") + } + // if errors.Is(err, gorm.ErrRecordNotFound) { + // t.Log("is not found error") + // } + // if err.Error() == "record not found" { + // t.Log(" string equal is not found error") + // } if err != nil { t.Fatal(err) } diff --git a/book/controller/logs/app.log b/book/controller/logs/app.log index 5428aba..a80ae5f 100644 --- a/book/controller/logs/app.log +++ b/book/controller/logs/app.log @@ -1,3 +1,6 @@ {"level":"debug","time":"2024-11-23T15:07:35+08:00","caller":"book/controller/book.go:60","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} {"level":"debug","time":"2024-11-23T15:11:42+08:00","caller":"book/controller/book.go:60","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} {"level":"debug","服务":"book-api","time":"2024-11-23T15:14:21+08:00","caller":"book/controller/book.go:60","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} +{"level":"debug","服务":"book-api","time":"2024-11-23T15:24:12+08:00","caller":"book/controller/book.go:61","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} +{"level":"debug","服务":"book-api","time":"2024-11-23T15:25:07+08:00","caller":"book/controller/book.go:61","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} +{"level":"debug","服务":"book-api","time":"2024-11-23T15:34:19+08:00","caller":"/Users/yumaojun/Projects/go-course/go17/book/controller/book.go:61","message":"req 请求信息: {\n \"title\": \"Go语言\",\n \"author\": \"will\",\n \"price\": 10,\n \"is_sale\": null\n}"} diff --git a/book/exception/README.md b/book/exception/README.md new file mode 100644 index 0000000..e27c957 --- /dev/null +++ b/book/exception/README.md @@ -0,0 +1,38 @@ +# 业务异常 + +```go +func TestGetBook(t *testing.T) { + book := controller.NewBookController() + ins, err := book.GetBook(context.Background(), &controller.GetBookRequest{ + Isbn: 100, + }) + + if errors.Is(err, gorm.ErrRecordNotFound) { + t.Log("is not found error") + } + if err.Error() == "record not found" { + t.Log(" string equal is not found error") + } + + if err != nil { + t.Fatal(err) + } + t.Log(ins) +} +``` + +设立一种统一的业务异常机制, 业内最常见的 就是 定义业务异常Code + ++ Code: 业务异常码 ++ Message: 异常的具体信息 ++ Reason: 导致这个异常的原因 + +业务异常是错误的一部分, 是一个error的一种实现 + +```go +// The error built-in interface type is the conventional interface for +// representing an error condition, with the nil value representing no error. +type error interface { + Error() string +} +``` \ No newline at end of file diff --git a/book/exception/errors.go b/book/exception/errors.go new file mode 100644 index 0000000..73a8625 --- /dev/null +++ b/book/exception/errors.go @@ -0,0 +1,19 @@ +package exception + +import "fmt" + +const ( + ERR_NOT_FOUND = 404 +) + +func IsNotFound(err error) bool { + if v, ok := (err).(*ApiExceptin); ok { + return v.Code == ERR_NOT_FOUND + } + + return false +} + +func ErrNotFound(format string, a ...any) *ApiExceptin { + return NewApiExceptin(ERR_NOT_FOUND, fmt.Sprintf(format, a...)) +} diff --git a/book/exception/exception.go b/book/exception/exception.go new file mode 100644 index 0000000..07e4412 --- /dev/null +++ b/book/exception/exception.go @@ -0,0 +1,21 @@ +package exception + +import ( + "fmt" +) + +func NewApiExceptin(code int, message string) *ApiExceptin { + return &ApiExceptin{ + Code: code, + Message: message, + } +} + +type ApiExceptin struct { + Code int `json:"code"` + Message string `json:"message"` +} + +func (e *ApiExceptin) Error() string { + return fmt.Sprintf("[%d] %s", e.Code, e.Message) +}