wip: custom logger and error handler

This commit is contained in:
2025-06-10 11:17:55 +01:00
parent 4935a65112
commit fae46f4bf7
7 changed files with 74 additions and 13 deletions
+17
View File
@@ -2,6 +2,7 @@ package api
import (
"fmt"
"log/slog"
"github.com/go-playground/validator/v10"
"github.com/gorilla/sessions"
@@ -11,12 +12,14 @@ import (
"github.com/hazemKrimi/crimson-vault/internal/lib"
"github.com/hazemKrimi/crimson-vault/internal/models"
"github.com/hazemKrimi/crimson-vault/internal/types"
)
type API struct {
ConfigDirectory string
instance *echo.Echo
db *models.DB
Logger *slog.Logger
}
func (api *API) Initialize() {
@@ -26,6 +29,19 @@ func (api *API) Initialize() {
db := &models.DB{}
ech := echo.New()
ech.Validator = &CustomValidator{validator: validator}
ech.HTTPErrorHandler = func(err error, context echo.Context) {
if context.Response().Committed {
return
}
custom, ok := err.(types.Error)
if ok {
context.JSONPretty(custom.Code, map[string][]string{"errors": custom.Messages}, " ")
}
ech.DefaultHTTPErrorHandler(err, context)
}
db.Connect(api.ConfigDirectory)
db.MigrateClients()
@@ -34,6 +50,7 @@ func (api *API) Initialize() {
api.instance = ech
api.db = db
api.instance.Use(api.LoggerMiddleware())
// TODO: Update with appropriate origins when finishing v1
api.instance.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
+28
View File
@@ -1,11 +1,14 @@
package api
import (
"context"
"log/slog"
"net/http"
"github.com/google/uuid"
"github.com/labstack/echo-contrib/session"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/hazemKrimi/crimson-vault/internal/types"
)
@@ -43,3 +46,28 @@ func (api *API) AuthSessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
return next(context)
}
}
func (api *API) LoggerMiddleware() echo.MiddlewareFunc {
return middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
LogStatus: true,
LogURI: true,
LogError: true,
HandleError: true,
LogMethod: true,
LogValuesFunc: func(logContext echo.Context, values middleware.RequestLoggerValues) error {
if values.Error == nil {
api.Logger.LogAttrs(context.Background(), slog.LevelInfo, "REQUEST",
slog.String("uri", values.URI),
slog.Int("status", values.Status),
)
} else {
api.Logger.LogAttrs(context.Background(), slog.LevelError, "REQUEST_ERROR",
slog.String("uri", values.URI),
slog.Int("status", values.Status),
slog.String("err", values.Error.Error()),
)
}
return nil
},
})
}
+7 -6
View File
@@ -15,13 +15,14 @@ func (api *API) ClientRoutes() {
func (api *API) UserRoutes() {
users := api.instance.Group("/api/users")
users.GET("/", api.GetAllUsersHandler)
users.POST("/", api.CreateUserHandler)
users.GET("/", api.GetUserHandler, api.AuthSessionMiddleware)
users.PUT("/", api.UpdateUserHandler, api.AuthSessionMiddleware)
users.PUT("/security/", api.UpdateUserSecurityCredentialsHandler, api.AuthSessionMiddleware)
users.PUT("/logo/", api.UpdateUserLogoHandler, middleware.BodyLimit("2M"), api.AuthSessionMiddleware)
users.DELETE("/", api.DeleteUserHandler, api.AuthSessionMiddleware)
users.DELETE("/logo/", api.DeleteUserLogoHandler, api.AuthSessionMiddleware)
users.GET("/me/", api.GetUserHandler, api.AuthSessionMiddleware)
users.PUT("/me/", api.UpdateUserHandler, api.AuthSessionMiddleware)
users.PUT("/me/security/", api.UpdateUserSecurityCredentialsHandler, api.AuthSessionMiddleware)
users.PUT("/me/logo/", api.UpdateUserLogoHandler, middleware.BodyLimit("2M"), api.AuthSessionMiddleware)
users.DELETE("/me/", api.DeleteUserHandler, api.AuthSessionMiddleware)
users.DELETE("/me/logo/", api.DeleteUserLogoHandler, api.AuthSessionMiddleware)
}
func (api *API) AuthRoutes() {
+1 -2
View File
@@ -180,8 +180,7 @@ func (api *API) UpdateUserLogoHandler(context echo.Context) error {
file, err := context.FormFile("logo")
if err != nil {
log.Println(fmt.Sprintf("Error updating logo for User: %v.", err))
return context.String(http.StatusBadRequest, "No image has been uploaded!")
return types.Error{Code: http.StatusBadRequest, Messages: []string{"No image has been uploaded!"}}
}
ext := strings.ToLower(filepath.Ext(file.Filename))
+5 -4
View File
@@ -6,7 +6,8 @@ import (
"regexp"
"github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4"
"github.com/hazemKrimi/crimson-vault/internal/types"
)
type CustomValidator struct {
@@ -16,7 +17,7 @@ type CustomValidator struct {
func (v *CustomValidator) Validate(i any) error {
if err := v.validator.Struct(i); err != nil {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
errors := make(map[string]string)
errors := make([]string, 0, 10)
for _, ve := range validationErrors {
field := ve.Field()
@@ -41,9 +42,9 @@ func (v *CustomValidator) Validate(i any) error {
msg = fmt.Sprintf("%s is not valid!", field)
}
errors[field] = msg
errors = append(errors, msg)
}
return echo.NewHTTPError(http.StatusBadRequest, errors)
return types.Error{Code: http.StatusBadRequest, Messages: errors}
}
}