diff options
author | 2025-04-25 03:07:37 +0530 | |
---|---|---|
committer | 2025-04-25 03:07:37 +0530 | |
commit | 7b9fe4639cafbcc35c860e23a20a2c0d2e29283d (patch) | |
tree | eef9b87745ed5e9b90f842c004941d12d705e7ac /backend/middleware/middleware.go | |
parent | d8856efd30dfcb05b26a5b66b5bb14cc0604e2b1 (diff) | |
download | finance-7b9fe4639cafbcc35c860e23a20a2c0d2e29283d.tar.gz finance-7b9fe4639cafbcc35c860e23a20a2c0d2e29283d.tar.bz2 finance-7b9fe4639cafbcc35c860e23a20a2c0d2e29283d.zip |
finance/backend: feat: set up logging and error handling
Diffstat (limited to 'backend/middleware/middleware.go')
-rw-r--r-- | backend/middleware/middleware.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/backend/middleware/middleware.go b/backend/middleware/middleware.go new file mode 100644 index 0000000..d319c47 --- /dev/null +++ b/backend/middleware/middleware.go @@ -0,0 +1,83 @@ +package middleware + +import ( + "finance/backend/internal/logger" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +// Logger is middleware for logging HTTP requests +func Logger(log *logger.Logger) gin.HandlerFunc { + return func(c *gin.Context) { + // Start timer + start := time.Now() + + // Process request + c.Next() + + // Calculate latency + latency := time.Since(start) + + // Log request + log.LogRequest( + c.Request.Method, + c.Request.URL.Path, + c.ClientIP(), + c.Request.UserAgent(), + c.Writer.Status(), + latency, + ) + } +} + +// ErrorHandler is middleware for handling errors +func ErrorHandler(log *logger.Logger) gin.HandlerFunc { + return func(c *gin.Context) { + c.Next() + + // Handle errors after request is processed + if len(c.Errors) > 0 { + for _, e := range c.Errors { + log.Error(e.Err) + } + + // Return last error to client if response wasn't already sent + if !c.Writer.Written() { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": c.Errors.Last().Error(), + }) + } + } + } +} + +// NotFoundHandler handles 404 errors +func NotFoundHandler(c *gin.Context) { + c.JSON(http.StatusNotFound, gin.H{ + "error": "Resource not found", + }) +} + +// MethodNotAllowedHandler handles 405 errors +func MethodNotAllowedHandler(c *gin.Context) { + c.JSON(http.StatusMethodNotAllowed, gin.H{ + "error": "Method not allowed", + }) +} + +// RecoveryWithLogger recovers from any panics and logs errors +func RecoveryWithLogger(log *logger.Logger) gin.HandlerFunc { + return func(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + log.Errorf("Panic recovered: %v", err) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ + "error": "Internal server error", + }) + } + }() + c.Next() + } +} |