]> localhost Git - tq-wave11-pf.git/commitdiff
feat better logs
authorJansen <[email protected]>
Thu, 7 Aug 2025 20:53:56 +0000 (16:53 -0400)
committerJansen <[email protected]>
Thu, 7 Aug 2025 20:53:56 +0000 (16:53 -0400)
internal/errors/errors.go
pkg/core/ingrendient.go
pkg/http/ingredient.go
pkg/http/util/errors.go
pkg/http/util/middlewares.go
pkg/http/util/parsers.go
pkg/util/ansi.go [new file with mode: 0644]

index 957d0c45ac8cf46c10b6b3419fe6d9ea7457c653..7c720c94d07f421274555b24e8c1865ce1c53e69 100644 (file)
@@ -40,14 +40,19 @@ func (e Error) Error() string {
 }
 
 func MapError(err error) Error {
-       switch err.Error() {
-       case "bad_id":
-               return Error{Code: BadIdError, Message: err.Error()}
-       case "name_in_use":
-               return Error{Code: ConflictError, Message: err.Error()}
-       case "not_found":
-               return Error{Code: NotFoundError, Message: err.Error()}
+       switch err := err.(type) {
+       case Error:
+               return err
        default:
-               return Error{Code: DefaultError, Message: "Something bad happened"}
+               switch err.Error() {
+               case "bad_id":
+                       return Error{Code: BadIdError, Message: err.Error()}
+               case "name_in_use":
+                       return Error{Code: ConflictError, Message: err.Error()}
+               case "not_found":
+                       return Error{Code: NotFoundError, Message: err.Error()}
+               default:
+                       return Error{Code: DefaultError, Message: "Something bad happened"}
+               }
        }
 }
index aa2deb88973ff2efddb303f96acd9fdd58ba8100..657e8823e724bce83f25e05416dd78a82d5fe89d 100644 (file)
@@ -9,16 +9,16 @@ import (
 type Ingredient struct {
        Id          int        `json:"id,omitempty"`
        Name        string     `json:"name"`
-       Quantity    int        `json:"quantity"`
+       Quantity    *int        `json:"quantity"`
        Description string     `json:"description"`
        CreatedAt   *time.Time `json:"-"`
        DeletedAt   *time.Time `json:"-"`
 }
 
 func (ingredient Ingredient) IsValid() error {
-       isMissingRequiredFields := ingredient.Name == "" || ingredient.Quantity == 0
+       isMissingRequiredFields := ingredient.Name == "" || ingredient.Quantity == nil
        isBadName := len(ingredient.Name) < 3
-       isBadQuantity := ingredient.Quantity < 0
+       isBadQuantity := *ingredient.Quantity < 0
 
        if isMissingRequiredFields {
                return errors.Error{Code: errors.BadInputError, Message: "fields required: name, quantity"}
index 49d744ecdb7540519d898c48584c41da7cae4940..efc534ebdcb1c4e947477adc7a2b07c58fceb008 100644 (file)
@@ -17,11 +17,11 @@ func (s *Server) ingredientHandleCreate(w shttp.ResponseWriter, r *shttp.Request
 
        ingredient, err := s.ingredients.Create(input)
        if err != nil {
-               util.HandleServiceError(w, err)
+               util.HandleServiceError(w, r, err)
                return
        }
 
-       util.ParseAndWriteResponse(w, ingredient, shttp.StatusCreated)
+       util.ParseAndWriteResponse(w, r, ingredient, shttp.StatusCreated)
 }
 
 func (s *Server) ingredientHandleUpdate(w shttp.ResponseWriter, r *shttp.Request) {
@@ -41,11 +41,11 @@ func (s *Server) ingredientHandleUpdate(w shttp.ResponseWriter, r *shttp.Request
 
        err = s.ingredients.Update(ingredient)
        if err != nil {
-               util.HandleServiceError(w, err)
+               util.HandleServiceError(w, r, err)
                return
        }
 
-       util.ParseAndWriteResponse(w, ingredient, shttp.StatusOK)
+       util.ParseAndWriteResponse(w, r, ingredient, shttp.StatusOK)
 }
 
 func (s *Server) ingredientHandleDelete(w shttp.ResponseWriter, r *shttp.Request) {
@@ -56,11 +56,11 @@ func (s *Server) ingredientHandleDelete(w shttp.ResponseWriter, r *shttp.Request
 
        err = s.ingredients.Delete(id)
        if err != nil {
-               util.HandleServiceError(w, err)
+               util.HandleServiceError(w, r, err)
                return
        }
 
-       util.ParseAndWriteResponse(w, struct{}{}, shttp.StatusNoContent)
+       util.ParseAndWriteResponse(w, r, struct{}{}, shttp.StatusNoContent)
 }
 
 func (s *Server) ingredientHandleGet(w shttp.ResponseWriter, r *shttp.Request) {
@@ -71,19 +71,19 @@ func (s *Server) ingredientHandleGet(w shttp.ResponseWriter, r *shttp.Request) {
 
        in, err := s.ingredients.Get(id)
        if err != nil {
-               util.HandleServiceError(w, err)
+               util.HandleServiceError(w, r, err)
                return
        }
 
-       util.ParseAndWriteResponse(w, in, shttp.StatusOK)
+       util.ParseAndWriteResponse(w, r, in, shttp.StatusOK)
 }
 
 func (s *Server) ingredientHandleList(w shttp.ResponseWriter, r *shttp.Request) {
        ingredients, err := s.ingredients.List()
        if err != nil {
-               util.HandleError(w, shttp.StatusInternalServerError, err.Error())
+               util.HandleError(w, r, shttp.StatusInternalServerError, err.Error())
                return
        }
 
-       util.ParseAndWriteResponse(w, ingredients, shttp.StatusOK)
+       util.ParseAndWriteResponse(w, r, ingredients, shttp.StatusOK)
 }
index 0d0357f5079faaf0aa7640cb023d56ff996e6f3b..7d4304e889a4fac1bbfe2ff35595dc0bf5b17dd4 100644 (file)
@@ -6,6 +6,7 @@ import (
        shttp "net/http"
 
        "jsdaj.tq/pf/internal/errors"
+       "jsdaj.tq/pf/pkg/util"
 )
 
 type httpError struct {
@@ -13,7 +14,11 @@ type httpError struct {
        Message string `json:"message"`
 }
 
-func HandleError(w shttp.ResponseWriter, status int, message string) {
+func HandleError(w shttp.ResponseWriter, r *shttp.Request, status int, message string) {
+       requestId := r.Context().Value(RequestId).(string)
+
+       log.Printf("%s!! %s :: %d :: %s%s\n", util.Red, requestId, status, message, util.Reset)
+
        response := httpError{
                Status:  status,
                Message: message,
@@ -28,22 +33,22 @@ func HandleError(w shttp.ResponseWriter, status int, message string) {
        w.Write(body)
 }
 
-func HandleErrorByCode(w shttp.ResponseWriter, status int) {
+func HandleErrorByCode(w shttp.ResponseWriter, r *shttp.Request, status int) {
        switch status {
        case shttp.StatusBadRequest:
-               HandleError(w, status, "Bad body")
+               HandleError(w, r, status, "Bad body")
        default:
-               HandleError(w, shttp.StatusInternalServerError, "Something went wrong")
+               HandleError(w, r, shttp.StatusInternalServerError, "Something went wrong")
        }
 }
 
-func HandleServiceError(w shttp.ResponseWriter, err error) {
+func HandleServiceError(w shttp.ResponseWriter, r *shttp.Request, err error) {
        switch err := err.(type) {
        case errors.Error:
                status := err.Code.MapToHTTP()
-               HandleError(w, status, err.Message)
+               HandleError(w, r, status, err.Message)
        default:
-               log.Printf("error: Expecting 'services.Error', received: %s\n", err)
-               HandleErrorByCode(w, shttp.StatusInternalServerError)
+               log.Printf("%s?? Expecting 'services.Error', received: %s%s\n", util.Yellow, err, util.Reset)
+               HandleErrorByCode(w, r, shttp.StatusInternalServerError)
        }
 }
index 1edeef3601edeb42dba7ac9d63c0444d993bf2eb..55111827230635fe16a3b2fb01013004a9f1828c 100644 (file)
@@ -1,13 +1,23 @@
 package util
 
 import (
+       "context"
+       "crypto/rand"
        "log"
        shttp "net/http"
+
+       "jsdaj.tq/pf/pkg/util"
 )
 
+type ContextKey string
+
+const RequestId ContextKey = "requestId"
+
 func middlewareLog(next shttp.Handler) shttp.Handler {
        return shttp.HandlerFunc(func(w shttp.ResponseWriter, r *shttp.Request) {
-               log.Printf("New request :: %s :: %s\n", r.Method, r.URL)
+               requestId := r.Context().Value(RequestId).(string)
+
+               log.Printf("%s** %s :: %s :: %s%s\n", util.White, requestId, r.Method, r.URL, util.Reset)
                next.ServeHTTP(w, r)
        })
 }
@@ -19,6 +29,14 @@ func middlewareJson(next shttp.Handler) shttp.Handler {
        })
 }
 
+func middlewareId(next shttp.Handler) shttp.Handler {
+       return shttp.HandlerFunc(func(w shttp.ResponseWriter, r *shttp.Request) {
+               ctx := context.WithValue(r.Context(), RequestId, rand.Text())
+               req := r.WithContext(ctx)
+               next.ServeHTTP(w, req)
+       })
+}
+
 func Middlewares(next shttp.Handler) shttp.Handler {
-       return middlewareLog(middlewareJson(next))
+       return middlewareId(middlewareLog(middlewareJson(next)))
 }
index 9cbad9ab0ef4e2bcfc8134a504a56c4e3fa8117b..9cedd4ac4eee8f34ebf9ceeb7f7032dc16f55ece 100644 (file)
@@ -2,18 +2,19 @@ package util
 
 import (
        "encoding/json"
+       serrors "errors"
        "log"
        "net/http"
        "strconv"
-       serrors "errors"
 
        "jsdaj.tq/pf/internal/errors"
+       "jsdaj.tq/pf/pkg/util"
 )
 
 func ParseParamIdAndErr(w http.ResponseWriter, r *http.Request) (int, error) {
        id, err := strconv.Atoi(r.PathValue("id"))
        if err != nil {
-               HandleServiceError(w, errors.MapError(serrors.New("bad_id")))
+               HandleServiceError(w, r, errors.MapError(serrors.New("bad_id")))
                return 0, err
        }
        return id, nil
@@ -22,20 +23,22 @@ func ParseParamIdAndErr(w http.ResponseWriter, r *http.Request) (int, error) {
 func ParseRequestAndErr[T any](w http.ResponseWriter, r *http.Request, input T) error {
        err := json.NewDecoder(r.Body).Decode(input)
        if err != nil {
-               log.Printf("!! %s\n", err)
-               HandleErrorByCode(w, http.StatusBadRequest)
+               HandleErrorByCode(w, r, http.StatusBadRequest)
                return err
        }
        return nil
 }
 
-func ParseAndWriteResponse[T any](w http.ResponseWriter, input T, status int) {
+func ParseAndWriteResponse[T any](w http.ResponseWriter, r *http.Request, input T, status int) {
+       requestId := r.Context().Value(RequestId).(string)
+
        response, err := json.Marshal(input)
        if err != nil {
-               HandleErrorByCode(w, http.StatusInternalServerError)
+               HandleErrorByCode(w, r, http.StatusInternalServerError)
                return
        }
 
        w.WriteHeader(status)
        w.Write(response)
+       log.Printf("%s** %s :: %d%s\n", util.Green, requestId, status, util.Reset)
 }
diff --git a/pkg/util/ansi.go b/pkg/util/ansi.go
new file mode 100644 (file)
index 0000000..4b127a6
--- /dev/null
@@ -0,0 +1,11 @@
+package util
+
+type Color string
+
+const (
+       Red    Color = "\x1b[31m"
+       Yellow Color = "\x1b[33m"
+       Green  Color = "\x1b[32m"
+       White  Color = "\x1b[97m"
+       Reset  Color = "\x1b[0m"
+)