2024-01-19 21:56:30 -06:00
|
|
|
package handler
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
|
|
rErrors "codeberg.org/danjones000/responsable-errors"
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
)
|
|
|
|
|
|
2024-01-22 20:08:03 -06:00
|
|
|
// Returns a gin middleware which writes a response with the error in the context.
|
2024-01-21 21:40:06 -06:00
|
|
|
func ErrorMiddleware(opts ...Option) gin.HandlerFunc {
|
|
|
|
|
conf := config{}
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
|
conf = opt(conf)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(conf.transformers) == 0 {
|
|
|
|
|
conf.transformers = []Transformer{ginTransformer}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-19 21:56:30 -06:00
|
|
|
return func(c *gin.Context) {
|
|
|
|
|
c.Next()
|
|
|
|
|
err := c.Errors.Last()
|
|
|
|
|
if err == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var re rErrors.ResponsableError
|
2024-01-21 21:40:06 -06:00
|
|
|
|
2024-01-19 21:56:30 -06:00
|
|
|
errors.As(err, &re)
|
2024-01-21 21:40:06 -06:00
|
|
|
// If we have at least one that's a ResponsableError, we should use it
|
2024-01-19 21:56:30 -06:00
|
|
|
for _, err = range c.Errors {
|
|
|
|
|
if re != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
2024-01-21 21:40:06 -06:00
|
|
|
errors.As(err, &re)
|
2024-01-19 21:56:30 -06:00
|
|
|
}
|
|
|
|
|
|
2024-01-21 21:40:06 -06:00
|
|
|
// Next, let's check our transformers
|
|
|
|
|
for _, trans := range conf.transformers {
|
|
|
|
|
if re != nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
re = trans(err)
|
|
|
|
|
}
|
2024-01-19 21:56:30 -06:00
|
|
|
|
2024-01-21 21:40:06 -06:00
|
|
|
// Still couldn't find one, so it's a 500
|
2024-01-19 21:56:30 -06:00
|
|
|
if re == nil {
|
2024-01-21 21:40:06 -06:00
|
|
|
re = rErrors.NewInternalError("%w", err)
|
2024-01-19 21:56:30 -06:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 10:29:58 -06:00
|
|
|
for _, logger := range conf.loggers {
|
|
|
|
|
logger(c, re)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.Set("rendered_error", re)
|
|
|
|
|
|
2024-01-22 20:08:03 -06:00
|
|
|
// @todo check a response hasn't already been sent
|
2024-01-21 15:45:19 -06:00
|
|
|
c.JSON(re.Status(), re)
|
2024-01-19 21:56:30 -06:00
|
|
|
}
|
|
|
|
|
}
|