Bug/error relating units foods (#987)

* fix type guard

* update typing

* rearrange methods

* spelling

* fix unknown error response

* update type check for none types

* add discord notification
This commit is contained in:
Hayden 2022-02-21 09:47:00 -09:00 committed by GitHub
parent 5310a94478
commit a897e180ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 21 deletions

View File

@ -47,3 +47,12 @@ jobs:
docker build --push --no-cache \ docker build --push --no-cache \
--tag hkotel/mealie:api-nightly \ --tag hkotel/mealie:api-nightly \
--platform linux/amd64,linux/arm64 . --platform linux/amd64,linux/arm64 .
#
# Build Discord Notification
#
- name: Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_NIGHTLY_WEBHOOK }}
uses: Ilshidur/action-discord@0.3.2
with:
args: "🚀 A New Nighlty Build of Mealie is ready"

View File

@ -1,4 +1,5 @@
from functools import wraps from functools import wraps
from uuid import UUID
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY, Session from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY, Session
@ -170,9 +171,13 @@ def auto_init(): # sourcery no-metrics
if val is None: if val is None:
raise ValueError(f"Expected 'id' to be provided for {key}") raise ValueError(f"Expected 'id' to be provided for {key}")
if isinstance(val, (str, int)): if isinstance(val, (str, int, UUID)):
instance = session.query(relation_cls).filter_by(**{get_attr: val}).one_or_none() instance = session.query(relation_cls).filter_by(**{get_attr: val}).one_or_none()
setattr(self, key, instance) setattr(self, key, instance)
else:
# If the value is not of the type defined above we assume that it isn't a valid id
# and try a different approach.
pass
elif relation_dir == MANYTOMANY: elif relation_dir == MANYTOMANY:
instances = handle_many_to_many(session, get_attr, relation_cls, val) instances = handle_many_to_many(session, get_attr, relation_cls, val)

View File

@ -142,7 +142,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
assets: list = None, assets: list = None,
notes: list[dict] = None, notes: list[dict] = None,
nutrition: dict = None, nutrition: dict = None,
recipe_ingredient: list[str] = None, recipe_ingredient: list[dict] = None,
settings: dict = None, settings: dict = None,
**_, **_,
) -> None: ) -> None:

View File

@ -117,6 +117,25 @@ router = UserAPIRouter(prefix="/recipes", tags=["Recipe: CRUD"])
@controller(router) @controller(router)
class RecipeController(BaseRecipeController): class RecipeController(BaseRecipeController):
def handle_exceptions(self, ex: Exception) -> None:
match type(ex):
case exceptions.PermissionDenied:
self.deps.logger.error("Permission Denied on recipe controller action")
raise HTTPException(status_code=403, detail=ErrorResponse.respond(message="Permission Denied"))
case exceptions.NoEntryFound:
self.deps.logger.error("No Entry Found on recipe controller action")
raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found"))
case sqlalchemy.exc.IntegrityError:
self.deps.logger.error("SQL Integrity Error on recipe controller action")
raise HTTPException(status_code=400, detail=ErrorResponse.respond(message="Recipe already exists"))
case _:
self.deps.logger.error("Unknown Error on recipe controller action")
self.deps.logger.exception(ex)
raise HTTPException(
status_code=500, detail=ErrorResponse.respond(message="Unknown Error", exception=str(ex))
)
# ======================================================================= # =======================================================================
# URL Scraping Operations # URL Scraping Operations
@ -212,24 +231,6 @@ class RecipeController(BaseRecipeController):
except Exception as e: except Exception as e:
self.handle_exceptions(e) self.handle_exceptions(e)
def handle_exceptions(self, ex: Exception) -> None:
match type(ex):
case exceptions.PermissionDenied:
self.deps.logger.error("Permission Denied on recipe controller action")
raise HTTPException(status_code=403, detail=ErrorResponse.respond(message="Permission Denied"))
case exceptions.NoEntryFound:
self.deps.logger.error("No Entry Found on recipe controller action")
raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found"))
case sqlalchemy.exc.IntegrityError:
self.deps.logger.error("SQL Integrity Error on recipe controller action")
raise HTTPException(status_code=400, detail=ErrorResponse.respond(message="Recipe already exists"))
case _:
self.deps.logger.error("Unknown Error on recipe controller action")
raise HTTPException(
status_code=500, detail=ErrorResponse.respond(message="Unknown Error", exception=ex)
)
@router.put("/{slug}") @router.put("/{slug}")
def update_one(self, slug: str, data: Recipe): def update_one(self, slug: str, data: Recipe):
"""Updates a recipe by existing slug and data.""" """Updates a recipe by existing slug and data."""

View File

@ -25,7 +25,7 @@ step_text = """Recipe steps as well as other fields in the recipe page support m
[My Link](https://beta.mealie.io) [My Link](https://beta.mealie.io)
**Imbed an image** **Embed an image**
Use the `height="100"` or `width="100"` attributes to set the size of the image. Use the `height="100"` or `width="100"` attributes to set the size of the image.
@ -158,6 +158,7 @@ class RecipeService(BaseService):
def update_one(self, slug: str, update_data: Recipe) -> Recipe: def update_one(self, slug: str, update_data: Recipe) -> Recipe:
recipe = self._pre_update_check(slug, update_data) recipe = self._pre_update_check(slug, update_data)
new_data = self.repos.recipes.update(slug, update_data) new_data = self.repos.recipes.update(slug, update_data)
self.check_assets(new_data, recipe.slug) self.check_assets(new_data, recipe.slug)
return new_data return new_data
@ -165,6 +166,7 @@ class RecipeService(BaseService):
def patch_one(self, slug: str, patch_data: Recipe) -> Recipe: def patch_one(self, slug: str, patch_data: Recipe) -> Recipe:
recipe = self._pre_update_check(slug, patch_data) recipe = self._pre_update_check(slug, patch_data)
recipe = self.repos.recipes.by_group(self.group.id).get_one(slug) recipe = self.repos.recipes.by_group(self.group.id).get_one(slug)
new_data = self.repos.recipes.patch(recipe.slug, patch_data) new_data = self.repos.recipes.patch(recipe.slug, patch_data)
self.check_assets(new_data, recipe.slug) self.check_assets(new_data, recipe.slug)