mirror of https://github.com/gin-gonic/gin.git
friendly error handling
due to c.Error() is not friendly to golint and useless returned, thought to remove it.
This commit is contained in:
parent
b860d8672d
commit
29568a5ecf
40
context.go
40
context.go
|
@ -199,9 +199,10 @@ func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
|
||||||
// AbortWithError calls `AbortWithStatus()` and `Error()` internally.
|
// AbortWithError calls `AbortWithStatus()` and `Error()` internally.
|
||||||
// This method stops the chain, writes the status code and pushes the specified error to `c.Errors`.
|
// This method stops the chain, writes the status code and pushes the specified error to `c.Errors`.
|
||||||
// See Context.Error() for more details.
|
// See Context.Error() for more details.
|
||||||
func (c *Context) AbortWithError(code int, err error) *Error {
|
func (c *Context) AbortWithError(code int, err error) {
|
||||||
c.AbortWithStatus(code)
|
c.AbortWithStatus(code)
|
||||||
return c.Error(err)
|
c.Error(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************/
|
/************************************/
|
||||||
|
@ -212,10 +213,10 @@ func (c *Context) AbortWithError(code int, err error) *Error {
|
||||||
// It's a good idea to call Error for each error that occurred during the resolution of a request.
|
// It's a good idea to call Error for each error that occurred during the resolution of a request.
|
||||||
// A middleware can be used to collect all the errors and push them to a database together,
|
// A middleware can be used to collect all the errors and push them to a database together,
|
||||||
// print a log, or append it in the HTTP response.
|
// print a log, or append it in the HTTP response.
|
||||||
// Error will panic if err is nil.
|
// Error will ignore if err is nil.
|
||||||
func (c *Context) Error(err error) *Error {
|
func (c *Context) Error(err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
panic("err is nil")
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedError, ok := err.(*Error)
|
parsedError, ok := err.(*Error)
|
||||||
|
@ -227,7 +228,30 @@ func (c *Context) Error(err error) *Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Errors = append(c.Errors, parsedError)
|
c.Errors = append(c.Errors, parsedError)
|
||||||
return parsedError
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorBindType attaches an error to the current context with specific ErrorType. The error is pushed to a list of errors.
|
||||||
|
// It's a good idea to call Error for each error that occurred during the resolution of a request.
|
||||||
|
// A middleware can be used to collect all the errors and push them to a database together,
|
||||||
|
// print a log, or append it in the HTTP response.
|
||||||
|
func (c *Context) ErrorBindType(err error, typ ErrorType) {
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedError, ok := err.(*Error)
|
||||||
|
if !ok {
|
||||||
|
parsedError = &Error{
|
||||||
|
Err: err,
|
||||||
|
Type: typ,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parsedError.SetType(typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Errors = append(c.Errors, parsedError)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************/
|
/************************************/
|
||||||
|
@ -633,7 +657,7 @@ func (c *Context) BindHeader(obj interface{}) error {
|
||||||
// It will abort the request with HTTP 400 if any error occurs.
|
// It will abort the request with HTTP 400 if any error occurs.
|
||||||
func (c *Context) BindUri(obj interface{}) error {
|
func (c *Context) BindUri(obj interface{}) error {
|
||||||
if err := c.ShouldBindUri(obj); err != nil {
|
if err := c.ShouldBindUri(obj); err != nil {
|
||||||
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
|
c.AbortWithError(http.StatusBadRequest, WrapError(err).SetType(ErrorTypeBind)) // nolint: errcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -644,7 +668,7 @@ func (c *Context) BindUri(obj interface{}) error {
|
||||||
// See the binding package.
|
// See the binding package.
|
||||||
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
|
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
|
||||||
if err := c.ShouldBindWith(obj, b); err != nil {
|
if err := c.ShouldBindWith(obj, b); err != nil {
|
||||||
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
|
c.AbortWithError(http.StatusBadRequest, WrapError(err).SetType(ErrorTypeBind)) // nolint: errcheck
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1354,19 +1354,12 @@ func TestContextError(t *testing.T) {
|
||||||
assert.Equal(t, ErrorTypePublic, c.Errors[1].Type)
|
assert.Equal(t, ErrorTypePublic, c.Errors[1].Type)
|
||||||
|
|
||||||
assert.Equal(t, c.Errors.Last(), c.Errors[1])
|
assert.Equal(t, c.Errors.Last(), c.Errors[1])
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if recover() == nil {
|
|
||||||
t.Error("didn't panic")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
c.Error(nil) // nolint: errcheck
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContextTypedError(t *testing.T) {
|
func TestContextTypedError(t *testing.T) {
|
||||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||||
c.Error(errors.New("externo 0")).SetType(ErrorTypePublic) // nolint: errcheck
|
c.ErrorBindType(errors.New("externo 0"), ErrorTypePublic)
|
||||||
c.Error(errors.New("interno 0")).SetType(ErrorTypePrivate) // nolint: errcheck
|
c.ErrorBindType(errors.New("interno 0"), ErrorTypePrivate)
|
||||||
|
|
||||||
for _, err := range c.Errors.ByType(ErrorTypePublic) {
|
for _, err := range c.Errors.ByType(ErrorTypePublic) {
|
||||||
assert.Equal(t, ErrorTypePublic, err.Type)
|
assert.Equal(t, ErrorTypePublic, err.Type)
|
||||||
|
@ -1381,7 +1374,8 @@ func TestContextAbortWithError(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
c.AbortWithError(http.StatusUnauthorized, errors.New("bad input")).SetMeta("some input") // nolint: errcheck
|
err := WrapError(errors.New("bad input")).SetMeta("some input")
|
||||||
|
c.AbortWithError(http.StatusUnauthorized, err) // nolint: errcheck
|
||||||
|
|
||||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||||
assert.Equal(t, abortIndex, c.index)
|
assert.Equal(t, abortIndex, c.index)
|
||||||
|
|
|
@ -41,6 +41,13 @@ type errorMsgs []*Error
|
||||||
|
|
||||||
var _ error = &Error{}
|
var _ error = &Error{}
|
||||||
|
|
||||||
|
// WrapError return Error wraps original error.
|
||||||
|
func WrapError(err error) *Error {
|
||||||
|
return &Error{
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetType sets the error's type.
|
// SetType sets the error's type.
|
||||||
func (msg *Error) SetType(flags ErrorType) *Error {
|
func (msg *Error) SetType(flags ErrorType) *Error {
|
||||||
msg.Type = flags
|
msg.Type = flags
|
||||||
|
|
Loading…
Reference in New Issue