IngredientUpdate(core.Ingredient) error
IngredientDeactivate(int) error
IngredientGet(int) (*core.Ingredient, error)
+ IngredientGetByName(name string) (*core.Ingredient, error)
// TODO: add search params
IngredientList() ([]core.Ingredient, error)
}
)
func (p *InmemoryPersistence) IngredientCreate(in core.Ingredient) (core.Ingredient, error) {
+ // IRW this would be an index, so np leaving it here
+ found, err := p.IngredientGetByName(in.Name)
+ if err != nil {
+ return core.Ingredient{}, err
+ }
+ if found != nil {
+ return core.Ingredient{}, errors.New("name_in_use")
+ }
+
+
id := len(p.ingredients) + 1
createdAt := time.Now()
func (p *InmemoryPersistence) IngredientGet(id int) (*core.Ingredient, error) {
if id < 0 || id > len(p.ingredients) {
- return nil, errors.New("not_found")
+ return nil, nil
}
return &p.ingredients[id-1], nil
}
+func (p *InmemoryPersistence) IngredientGetByName(name string) (*core.Ingredient, error) {
+ for _, in := range p.ingredients {
+ if in.Name == name {
+ return &in, nil
+ }
+ }
+ return nil, nil
+}
+
func (p *InmemoryPersistence) IngredientList() ([]core.Ingredient, error) {
return p.ingredients, nil
}
import (
"encoding/json"
+ "log"
shttp "net/http"
"jsdaj.tq/pf/pkg/services"
}
}
-func handleServiceError(w shttp.ResponseWriter, err services.Error) {
- status := err.Code.MapToHTTP()
- handleError(w, status, err.Message)
+func handleServiceError(w shttp.ResponseWriter, err error) {
+ switch err.(type) {
+ case services.Error:
+ e := err.(services.Error)
+ status := e.Code.MapToHTTP()
+ handleError(w, status, e.Message)
+ default:
+ log.Printf("error: Expecting 'services.Error', received: %s\n", err)
+ handleErrorByCode(w, shttp.StatusInternalServerError)
+ }
}
ingredient, err := s.ingredients.Create(input)
if err != nil {
- handleError(w, shttp.StatusInternalServerError, err.Error())
+ handleServiceError(w, err)
return
}
return
}
+ w.WriteHeader(shttp.StatusCreated)
w.Write(response)
}
const (
DefaultError ErrorCode = iota
BadInputError
+ ConflictError
)
func (c ErrorCode) MapToHTTP() int {
switch c {
case BadInputError:
return 400
+ case ConflictError:
+ return 409
default:
return 500
}
}
func (e Error) Error() string {
- return fmt.Sprintf("%d :: %s", e.Code, e.Message)
+ return fmt.Sprintf("(%d)%s", e.Code, e.Message)
}
}
func (s *Ingredient) Create(ingredient core.Ingredient) (*core.Ingredient, error) {
+ isMissingRequiredFields := ingredient.Name == "" || ingredient.Quantity == 0
+ isBadName := len(ingredient.Name) < 3
+ isBadQuantity := ingredient.Quantity < 0
+
+ if isMissingRequiredFields {
+ return nil, Error{Code: BadInputError, Message: "fields required: name, quantity"}
+ }
+ if isBadName {
+ return nil, Error{Code: BadInputError, Message: "name should be have more than 2 chars"}
+ }
+ if isBadQuantity {
+ return nil, Error{Code: BadInputError, Message: "quantity should be positive"}
+ }
+
ingredient, err := s.repository.IngredientCreate(ingredient)
if err != nil {
+ if err.Error() == "name_in_use" {
+ return nil, Error{Code: ConflictError, Message: err.Error()}
+ }
return nil, err
}
return &ingredient, nil