✨ Add middleware
This commit is contained in:
parent
447f3b38ef
commit
4c635ffbe8
4 changed files with 147 additions and 2 deletions
3
go.mod
3
go.mod
|
|
@ -3,8 +3,9 @@ module codeberg.org/danjones000/gin-error-handler
|
||||||
go 1.21.5
|
go 1.21.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
codeberg.org/danjones000/responsable-errors v0.1.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/stretchr/testify v1.8.3
|
github.com/stretchr/testify v1.8.4
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
|
||||||
5
go.sum
5
go.sum
|
|
@ -1,3 +1,5 @@
|
||||||
|
codeberg.org/danjones000/responsable-errors v0.1.1 h1:WTWo0egPNsp+kEKRK8R+yc/bfdEDUbwEjMnqgA7IklA=
|
||||||
|
codeberg.org/danjones000/responsable-errors v0.1.1/go.mod h1:susEj39A/bflyej4tRirtuVKkmfUdhR2Skljwd/1ndI=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
|
|
@ -54,8 +56,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
|
||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
|
|
||||||
41
middleware.go
Normal file
41
middleware.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
rErrors "codeberg.org/danjones000/responsable-errors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ErrorMiddleware() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Next()
|
||||||
|
err := c.Errors.Last()
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var re rErrors.ResponsableError
|
||||||
|
errors.As(err, &re)
|
||||||
|
for _, err = range c.Errors {
|
||||||
|
errors.As(err, &re)
|
||||||
|
if re != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo we need to add some way to do custom handling
|
||||||
|
|
||||||
|
// @todo Refactor this with 👆
|
||||||
|
if re == nil {
|
||||||
|
switch err.Type {
|
||||||
|
case gin.ErrorTypePrivate:
|
||||||
|
re = rErrors.NewInternalError("%w", err)
|
||||||
|
default:
|
||||||
|
re = rErrors.NewBadRequest("%w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(re.GetStatus(), gin.H{"error": re.GetMsg()})
|
||||||
|
}
|
||||||
|
}
|
||||||
100
middleware_test.go
Normal file
100
middleware_test.go
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
rErrors "codeberg.org/danjones000/responsable-errors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMiddleware(t *testing.T) {
|
||||||
|
suite.Run(t, new(MiddlewareTestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
type MiddlewareTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
w *httptest.ResponseRecorder
|
||||||
|
ctx *gin.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) SetupTest() {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
s.w = httptest.NewRecorder()
|
||||||
|
s.ctx, _ = gin.CreateTestContext(s.w)
|
||||||
|
s.ctx.Request = new(http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TearDownTest() {
|
||||||
|
s.w = nil
|
||||||
|
s.ctx = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) do(err ...error) {
|
||||||
|
for _, e := range err {
|
||||||
|
s.ctx.Error(e)
|
||||||
|
}
|
||||||
|
ErrorMiddleware()(s.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) doParse(err ...error) map[string]any {
|
||||||
|
s.do(err...)
|
||||||
|
var out map[string]any
|
||||||
|
jsonErr := json.Unmarshal(s.w.Body.Bytes(), &out)
|
||||||
|
s.Assert().Nil(jsonErr)
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TestNoError() {
|
||||||
|
s.do()
|
||||||
|
s.Assert().Equal("", s.w.Body.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TestResError() {
|
||||||
|
msg := "I can't find it"
|
||||||
|
err := rErrors.NewNotFound(msg)
|
||||||
|
out := s.doParse(err)
|
||||||
|
|
||||||
|
outMsg, ok := out["error"].(string)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
s.Assert().Equal(msg, outMsg)
|
||||||
|
s.Assert().Equal(http.StatusNotFound, s.w.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TestGinError() {
|
||||||
|
msg := "I don't like this"
|
||||||
|
err := &gin.Error{errors.New(msg), gin.ErrorTypePublic, nil}
|
||||||
|
out := s.doParse(err)
|
||||||
|
|
||||||
|
outMsg, ok := out["error"].(string)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
s.Assert().Equal(msg, outMsg)
|
||||||
|
s.Assert().Equal(http.StatusBadRequest, s.w.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TestGinErrorPrivate() {
|
||||||
|
msg := "Don't do this"
|
||||||
|
err := &gin.Error{errors.New(msg), gin.ErrorTypePrivate, nil}
|
||||||
|
out := s.doParse(err)
|
||||||
|
|
||||||
|
outMsg, ok := out["error"].(string)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
s.Assert().Equal("Unknown Error", outMsg)
|
||||||
|
s.Assert().Equal(http.StatusInternalServerError, s.w.Code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MiddlewareTestSuite) TestOtherError() {
|
||||||
|
msg := "Don't do this"
|
||||||
|
err := errors.New(msg)
|
||||||
|
out := s.doParse(err)
|
||||||
|
|
||||||
|
outMsg, ok := out["error"].(string)
|
||||||
|
s.Assert().True(ok)
|
||||||
|
s.Assert().Equal("Unknown Error", outMsg)
|
||||||
|
s.Assert().Equal(http.StatusInternalServerError, s.w.Code)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue