mirror of
https://github.com/hazemKrimi/crimson-vault.git
synced 2026-05-01 18:20:27 +00:00
wip: custom logger and error handler
This commit is contained in:
@@ -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{"*"},
|
||||
|
||||
@@ -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
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package types
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Error struct {
|
||||
Messages []string
|
||||
Code int
|
||||
}
|
||||
|
||||
func (err Error) Error() string {
|
||||
return fmt.Sprintf("%v",
|
||||
err.Messages)
|
||||
}
|
||||
Reference in New Issue
Block a user