go17/book/exception/README.md

1.6 KiB

业务异常

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的一种实现

// 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
}

异常实现

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)
}

业务异常如何 打通到接口层

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()})
	}
}