Add middleware

This commit is contained in:
Dan Jones 2024-01-19 21:56:30 -06:00
commit 4c635ffbe8
4 changed files with 147 additions and 2 deletions

3
go.mod
View file

@ -3,8 +3,9 @@ module codeberg.org/danjones000/gin-error-handler
go 1.21.5
require (
codeberg.org/danjones000/responsable-errors v0.1.1
github.com/gin-gonic/gin v1.9.1
github.com/stretchr/testify v1.8.3
github.com/stretchr/testify v1.8.4
)
require (

5
go.sum
View file

@ -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.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
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.1/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.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/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=

41
middleware.go Normal file
View 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
View 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)
}