# 业务异常 ```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 } ``` 异常实现 ```go type ApiExceptin struct { HttpCode int `json:"-"` Code int `json:"code"` Message string `json:"message"` } func (e *ApiExceptin) WithHttpCode(httpCode int) *ApiExceptin { e.HttpCode = httpCode return e } func (e *ApiExceptin) Error() string { return fmt.Sprintf("[%d] %s", e.Code, e.Message) } ``` ## 业务异常如何 打通到接口层 ```go func Failed(ctx *gin.Context, err error) { // 断言, 是我们定义的标准异常,之间使用异常对象本事 if v, ok := err.(*exception.ApiExceptin); ok { if v.HttpCode == 0 { v.HttpCode = 500 } ctx.JSON(v.HttpCode, v) } else { ctx.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": err.Error()}) } } ```