API / internal /api /middleware /error_handler.go
sshinmen's picture
Update HF Spaces deployment with latest changes
2e6b65c
Raw
History Blame Contribute Delete
2.01 kB
package middleware
import (
"errors"
"net/http"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/router-for-me/CLIProxyAPI/v6/internal/application/dto"
domainerrors "github.com/router-for-me/CLIProxyAPI/v6/internal/domain/errors"
)
// ErrorHandler returns a middleware that handles domain errors
func ErrorHandler(logger *logrus.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
// Check if there are any errors
if len(c.Errors) == 0 {
return
}
// Get the last error
err := c.Errors.Last().Err
requestID := c.GetString("request_id")
// Handle domain errors
if domainErr, ok := err.(*domainerrors.DomainError); ok {
handleDomainError(c, domainErr, requestID, logger)
return
}
// Handle wrapped domain errors
var domainErr *domainerrors.DomainError
if errors.As(err, &domainErr) {
handleDomainError(c, domainErr, requestID, logger)
return
}
// Unknown error - log full details but return generic message
logger.WithError(err).
WithField("request_id", requestID).
WithField("path", c.Request.URL.Path).
Error("Unhandled error")
c.JSON(http.StatusInternalServerError, dto.InternalErrorResponse{
Success: false,
Error: "An unexpected error occurred",
RequestID: requestID,
})
}
}
func handleDomainError(c *gin.Context, err *domainerrors.DomainError, requestID string, logger *logrus.Logger) {
// Log with appropriate level based on status code
entry := logger.WithError(err).
WithField("request_id", requestID).
WithField("error_code", err.Code).
WithField("path", c.Request.URL.Path)
statusCode := err.HTTPStatusCode()
if statusCode >= 500 {
entry.Error("Server error")
} else if statusCode >= 400 {
entry.Warn("Client error")
}
// Return structured error response
c.JSON(statusCode, dto.ErrorResponse{
Success: false,
Error: dto.ErrorInfo{
Code: string(err.Code),
Message: err.Message,
Details: err.Details,
},
RequestID: requestID,
})
}