✨ 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