mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-05-24 01:12:54 -04:00
refactor exception handler to use platform feature instead of home rolled handler
This commit is contained in:
parent
6418a10428
commit
4ca354a0c5
@ -3,6 +3,7 @@ from fastapi import FastAPI
|
|||||||
from fastapi.middleware.gzip import GZipMiddleware
|
from fastapi.middleware.gzip import GZipMiddleware
|
||||||
from fastapi.routing import APIRoute
|
from fastapi.routing import APIRoute
|
||||||
|
|
||||||
|
from mealie import errors
|
||||||
from mealie.core.config import get_app_settings
|
from mealie.core.config import get_app_settings
|
||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.core.settings.static import APP_VERSION
|
from mealie.core.settings.static import APP_VERSION
|
||||||
@ -77,6 +78,8 @@ def api_routers():
|
|||||||
app.include_router(media_router)
|
app.include_router(media_router)
|
||||||
app.include_router(utility_routes.router)
|
app.include_router(utility_routes.router)
|
||||||
|
|
||||||
|
errors.mount_handlers(app, logger=get_logger())
|
||||||
|
|
||||||
|
|
||||||
api_routers()
|
api_routers()
|
||||||
|
|
||||||
|
@ -1,8 +1,3 @@
|
|||||||
from sqlite3 import IntegrityError
|
|
||||||
|
|
||||||
from mealie.lang.providers import Translator
|
|
||||||
|
|
||||||
|
|
||||||
class UnexpectedNone(Exception):
|
class UnexpectedNone(Exception):
|
||||||
"""Exception raised when a value is None when it should not be."""
|
"""Exception raised when a value is None when it should not be."""
|
||||||
|
|
||||||
@ -28,15 +23,3 @@ class NoEntryFound(Exception):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def mealie_registered_exceptions(t: Translator) -> dict:
|
|
||||||
"""
|
|
||||||
This function returns a dictionary of all the globally registered exceptions in the Mealie application.
|
|
||||||
"""
|
|
||||||
|
|
||||||
return {
|
|
||||||
PermissionDenied: t.t("exceptions.permission-denied"),
|
|
||||||
NoEntryFound: t.t("exceptions.no-entry-found"),
|
|
||||||
IntegrityError: t.t("exceptions.integrity-error"),
|
|
||||||
}
|
|
||||||
|
5
mealie/errors/__init__.py
Normal file
5
mealie/errors/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from .handlers import mount_handlers
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"mount_handlers",
|
||||||
|
]
|
70
mealie/errors/handlers.py
Normal file
70
mealie/errors/handlers.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
from logging import Logger
|
||||||
|
|
||||||
|
import fastapi
|
||||||
|
import sqlalchemy
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from mealie.core import exceptions
|
||||||
|
from mealie.lang.providers import local_provider
|
||||||
|
from mealie.schema.response.responses import ErrorResponse
|
||||||
|
|
||||||
|
|
||||||
|
def json_error(content, status_code):
|
||||||
|
return JSONResponse(content={"detail": content}, status_code=status_code)
|
||||||
|
|
||||||
|
|
||||||
|
def mount_handlers(app: fastapi.FastAPI, logger: Logger) -> None:
|
||||||
|
"""
|
||||||
|
mount_handlers is a function that mounts the exception handlers to the FastAPI app.
|
||||||
|
It provides a common handling point for known exceptions and provides a consistent
|
||||||
|
response format.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@app.exception_handler(exceptions.PermissionDenied)
|
||||||
|
def _(req: fastapi.Request, exc: exceptions.PermissionDenied):
|
||||||
|
t = local_provider(req.headers.get("Accept-Language"))
|
||||||
|
|
||||||
|
return json_error(
|
||||||
|
ErrorResponse.respond(
|
||||||
|
message=t.t("exceptions.permission-denied"),
|
||||||
|
exception=exc.__class__.__name__,
|
||||||
|
),
|
||||||
|
403,
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.exception_handler(exceptions.NoEntryFound)
|
||||||
|
def _(req: fastapi.Request, exc: exceptions.NoEntryFound):
|
||||||
|
t = local_provider(req.headers.get("Accept-Language"))
|
||||||
|
|
||||||
|
return json_error(
|
||||||
|
ErrorResponse.respond(
|
||||||
|
t.t("exceptions.no-entry-found"),
|
||||||
|
exception=exc.__class__.__name__,
|
||||||
|
),
|
||||||
|
404,
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.exception_handler(sqlalchemy.exc.IntegrityError)
|
||||||
|
def _(req: fastapi.Request, exc: sqlalchemy.exc.IntegrityError):
|
||||||
|
t = local_provider(req.headers.get("Accept-Language"))
|
||||||
|
|
||||||
|
return json_error(
|
||||||
|
ErrorResponse.respond(
|
||||||
|
message=t.t("exceptions.integrity-error"),
|
||||||
|
exception=exc.__class__.__name__,
|
||||||
|
),
|
||||||
|
400,
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.exception_handler(Exception)
|
||||||
|
def _(req: fastapi.Request, exc: Exception):
|
||||||
|
logger.error("Unknown error")
|
||||||
|
logger.exception(exc)
|
||||||
|
|
||||||
|
return json_error(
|
||||||
|
ErrorResponse.respond(
|
||||||
|
message="Unknown Error",
|
||||||
|
exception=exc.__class__.__name__,
|
||||||
|
),
|
||||||
|
500,
|
||||||
|
)
|
@ -7,7 +7,6 @@ from sqlalchemy.orm import Session
|
|||||||
|
|
||||||
from mealie.core.config import get_app_dirs, get_app_settings
|
from mealie.core.config import get_app_dirs, get_app_settings
|
||||||
from mealie.core.dependencies.dependencies import get_admin_user, get_current_user, get_integration_id
|
from mealie.core.dependencies.dependencies import get_admin_user, get_current_user, get_integration_id
|
||||||
from mealie.core.exceptions import mealie_registered_exceptions
|
|
||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.core.settings.directories import AppDirectories
|
from mealie.core.settings.directories import AppDirectories
|
||||||
from mealie.core.settings.settings import AppSettings
|
from mealie.core.settings.settings import AppSettings
|
||||||
@ -86,12 +85,6 @@ class BaseUserController(_BaseController):
|
|||||||
# Manual Cache
|
# Manual Cache
|
||||||
_checks: OperationChecks
|
_checks: OperationChecks
|
||||||
|
|
||||||
def registered_exceptions(self, ex: type[Exception]) -> str:
|
|
||||||
registered = {
|
|
||||||
**mealie_registered_exceptions(self.translator),
|
|
||||||
}
|
|
||||||
return registered.get(ex, self.t("generic.server-error"))
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def group_id(self) -> UUID4:
|
def group_id(self) -> UUID4:
|
||||||
return self.user.group_id
|
return self.user.group_id
|
||||||
|
@ -34,33 +34,20 @@ class HttpRepo(Generic[C, R, U]):
|
|||||||
self,
|
self,
|
||||||
repo: RepositoryGeneric,
|
repo: RepositoryGeneric,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
exception_msgs: Callable[[type[Exception]], str] | None = None,
|
|
||||||
default_message: str | None = None,
|
default_message: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.repo = repo
|
self.repo = repo
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.exception_msgs = exception_msgs
|
|
||||||
|
|
||||||
if default_message:
|
if default_message:
|
||||||
self.default_message = default_message
|
self.default_message = default_message
|
||||||
|
|
||||||
def get_exception_message(self, ext: Exception) -> str:
|
|
||||||
if self.exception_msgs:
|
|
||||||
return self.exception_msgs(type(ext))
|
|
||||||
return self.default_message
|
|
||||||
|
|
||||||
def handle_exception(self, ex: Exception) -> None:
|
def handle_exception(self, ex: Exception) -> None:
|
||||||
# Cleanup
|
# Cleanup
|
||||||
self.logger.exception(ex)
|
self.logger.exception(ex)
|
||||||
self.repo.session.rollback()
|
self.repo.session.rollback()
|
||||||
|
|
||||||
# Respond
|
raise ex
|
||||||
msg = self.get_exception_message(ex)
|
|
||||||
|
|
||||||
raise HTTPException(
|
|
||||||
status.HTTP_400_BAD_REQUEST,
|
|
||||||
detail=ErrorResponse.respond(message=msg, exception=str(ex)),
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_one(self, data: C) -> R | None:
|
def create_one(self, data: C) -> R | None:
|
||||||
item: R | None = None
|
item: R | None = None
|
||||||
|
@ -33,7 +33,6 @@ class AdminUserManagementRoutes(BaseAdminController):
|
|||||||
return HttpRepo[GroupBase, GroupInDB, GroupAdminUpdate](
|
return HttpRepo[GroupBase, GroupInDB, GroupAdminUpdate](
|
||||||
self.repo,
|
self.repo,
|
||||||
self.logger,
|
self.logger,
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@router.get("", response_model=GroupPagination)
|
@router.get("", response_model=GroupPagination)
|
||||||
|
@ -26,7 +26,7 @@ class AdminUserManagementRoutes(BaseAdminController):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[UserIn, UserOut, UserOut](self.repo, self.logger, self.registered_exceptions)
|
return HttpRepo[UserIn, UserOut, UserOut](self.repo, self.logger)
|
||||||
|
|
||||||
@router.get("", response_model=UserPagination)
|
@router.get("", response_model=UserPagination)
|
||||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||||
|
@ -30,7 +30,7 @@ class RecipeCommentRoutes(BaseUserController):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def mixins(self) -> HttpRepo:
|
def mixins(self) -> HttpRepo:
|
||||||
return HttpRepo(self.repo, self.logger, self.registered_exceptions, self.t("generic.server-error"))
|
return HttpRepo(self.repo, self.logger, self.t("generic.server-error"))
|
||||||
|
|
||||||
def _check_comment_belongs_to_user(self, item_id: UUID4) -> None:
|
def _check_comment_belongs_to_user(self, item_id: UUID4) -> None:
|
||||||
comment = self.repo.get_one(item_id)
|
comment = self.repo.get_one(item_id)
|
||||||
|
@ -3,7 +3,6 @@ from functools import cached_property
|
|||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from pydantic import UUID4
|
from pydantic import UUID4
|
||||||
|
|
||||||
from mealie.core.exceptions import mealie_registered_exceptions
|
|
||||||
from mealie.routes._base import BaseCrudController, controller
|
from mealie.routes._base import BaseCrudController, controller
|
||||||
from mealie.routes._base.mixins import HttpRepo
|
from mealie.routes._base.mixins import HttpRepo
|
||||||
from mealie.routes._base.routers import MealieCrudRoute
|
from mealie.routes._base.routers import MealieCrudRoute
|
||||||
@ -27,19 +26,9 @@ class GroupCookbookController(BaseCrudController):
|
|||||||
def repo(self):
|
def repo(self):
|
||||||
return self.repos.cookbooks.by_group(self.group_id)
|
return self.repos.cookbooks.by_group(self.group_id)
|
||||||
|
|
||||||
def registered_exceptions(self, ex: type[Exception]) -> str:
|
|
||||||
registered = {
|
|
||||||
**mealie_registered_exceptions(self.translator),
|
|
||||||
}
|
|
||||||
return registered.get(ex, self.t("generic.server-error"))
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[CreateCookBook, ReadCookBook, UpdateCookBook](
|
return HttpRepo[CreateCookBook, ReadCookBook, UpdateCookBook](self.repo, self.logger)
|
||||||
self.repo,
|
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.get("", response_model=CookBookPagination)
|
@router.get("", response_model=CookBookPagination)
|
||||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||||
|
@ -49,7 +49,7 @@ class GroupEventsNotifierController(BaseUserController):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def mixins(self) -> HttpRepo:
|
def mixins(self) -> HttpRepo:
|
||||||
return HttpRepo(self.repo, self.logger, self.registered_exceptions, self.t("generic.server-error"))
|
return HttpRepo(self.repo, self.logger)
|
||||||
|
|
||||||
@router.get("", response_model=GroupEventPagination)
|
@router.get("", response_model=GroupEventPagination)
|
||||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||||
|
@ -3,7 +3,6 @@ from functools import cached_property
|
|||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException
|
||||||
from pydantic import UUID4
|
from pydantic import UUID4
|
||||||
|
|
||||||
from mealie.core.exceptions import mealie_registered_exceptions
|
|
||||||
from mealie.routes._base.base_controllers import BaseUserController
|
from mealie.routes._base.base_controllers import BaseUserController
|
||||||
from mealie.routes._base.controller import controller
|
from mealie.routes._base.controller import controller
|
||||||
from mealie.routes._base.mixins import HttpRepo
|
from mealie.routes._base.mixins import HttpRepo
|
||||||
@ -19,18 +18,9 @@ class GroupReportsController(BaseUserController):
|
|||||||
def repo(self):
|
def repo(self):
|
||||||
return self.repos.group_reports.by_group(self.user.group_id)
|
return self.repos.group_reports.by_group(self.user.group_id)
|
||||||
|
|
||||||
def registered_exceptions(self, ex: type[Exception]) -> str:
|
|
||||||
return {
|
|
||||||
**mealie_registered_exceptions(self.translator),
|
|
||||||
}.get(ex, self.t("generic.server-error"))
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[ReportCreate, ReportOut, ReportCreate](
|
return HttpRepo[ReportCreate, ReportOut, ReportCreate](self.repo, self.logger)
|
||||||
self.repo,
|
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.get("", response_model=list[ReportSummary])
|
@router.get("", response_model=list[ReportSummary])
|
||||||
def get_all(self, report_type: ReportCategory | None = None):
|
def get_all(self, report_type: ReportCategory | None = None):
|
||||||
|
@ -38,7 +38,7 @@ class MultiPurposeLabelsController(BaseUserController):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def mixins(self) -> HttpRepo:
|
def mixins(self) -> HttpRepo:
|
||||||
return HttpRepo(self.repo, self.logger, self.registered_exceptions, self.t("generic.server-error"))
|
return HttpRepo(self.repo, self.logger)
|
||||||
|
|
||||||
@router.get("", response_model=MultiPurposeLabelPagination)
|
@router.get("", response_model=MultiPurposeLabelPagination)
|
||||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||||
|
@ -3,7 +3,6 @@ from functools import cached_property
|
|||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
|
||||||
from mealie.core.exceptions import mealie_registered_exceptions
|
|
||||||
from mealie.repos.repository_meals import RepositoryMeals
|
from mealie.repos.repository_meals import RepositoryMeals
|
||||||
from mealie.routes._base import controller
|
from mealie.routes._base import controller
|
||||||
from mealie.routes._base.base_controllers import BaseCrudController
|
from mealie.routes._base.base_controllers import BaseCrudController
|
||||||
@ -26,19 +25,9 @@ class GroupMealplanController(BaseCrudController):
|
|||||||
def repo(self) -> RepositoryMeals:
|
def repo(self) -> RepositoryMeals:
|
||||||
return self.repos.meals.by_group(self.group_id)
|
return self.repos.meals.by_group(self.group_id)
|
||||||
|
|
||||||
def registered_exceptions(self, ex: type[Exception]) -> str:
|
|
||||||
registered = {
|
|
||||||
**mealie_registered_exceptions(self.translator),
|
|
||||||
}
|
|
||||||
return registered.get(ex, self.t("generic.server-error"))
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry](
|
return HttpRepo[CreatePlanEntry, ReadPlanEntry, UpdatePlanEntry](self.repo, self.logger)
|
||||||
self.repo,
|
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.get("/today")
|
@router.get("/today")
|
||||||
def get_todays_meals(self):
|
def get_todays_meals(self):
|
||||||
|
@ -165,7 +165,7 @@ class ShoppingListController(BaseCrudController):
|
|||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self) -> HttpRepo[ShoppingListCreate, ShoppingListOut, ShoppingListSave]:
|
def mixins(self) -> HttpRepo[ShoppingListCreate, ShoppingListOut, ShoppingListSave]:
|
||||||
return HttpRepo(self.repo, self.logger, self.registered_exceptions, self.t("generic.server-error"))
|
return HttpRepo(self.repo, self.logger, self.t("generic.server-error"))
|
||||||
|
|
||||||
@router.get("", response_model=ShoppingListPagination)
|
@router.get("", response_model=ShoppingListPagination)
|
||||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||||
|
@ -3,7 +3,6 @@ from shutil import copyfileobj
|
|||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
import sqlalchemy
|
|
||||||
from fastapi import BackgroundTasks, Depends, File, Form, HTTPException, Query, Request, status
|
from fastapi import BackgroundTasks, Depends, File, Form, HTTPException, Query, Request, status
|
||||||
from fastapi.datastructures import UploadFile
|
from fastapi.datastructures import UploadFile
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
@ -11,7 +10,6 @@ from pydantic import UUID4, BaseModel, Field
|
|||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from starlette.responses import FileResponse
|
from starlette.responses import FileResponse
|
||||||
|
|
||||||
from mealie.core import exceptions
|
|
||||||
from mealie.core.dependencies import temporary_zip_path
|
from mealie.core.dependencies import temporary_zip_path
|
||||||
from mealie.core.dependencies.dependencies import temporary_dir, validate_recipe_token
|
from mealie.core.dependencies.dependencies import temporary_dir, validate_recipe_token
|
||||||
from mealie.core.security import create_recipe_slug_token
|
from mealie.core.security import create_recipe_slug_token
|
||||||
@ -145,25 +143,6 @@ router = UserAPIRouter(prefix="/recipes", tags=["Recipe: CRUD"], route_class=Mea
|
|||||||
|
|
||||||
@controller(router)
|
@controller(router)
|
||||||
class RecipeController(BaseRecipeController):
|
class RecipeController(BaseRecipeController):
|
||||||
def handle_exceptions(self, ex: Exception) -> None:
|
|
||||||
thrownType = type(ex)
|
|
||||||
|
|
||||||
if thrownType == exceptions.PermissionDenied:
|
|
||||||
self.logger.error("Permission Denied on recipe controller action")
|
|
||||||
raise HTTPException(status_code=403, detail=ErrorResponse.respond(message="Permission Denied"))
|
|
||||||
elif thrownType == exceptions.NoEntryFound:
|
|
||||||
self.logger.error("No Entry Found on recipe controller action")
|
|
||||||
raise HTTPException(status_code=404, detail=ErrorResponse.respond(message="No Entry Found"))
|
|
||||||
elif thrownType == sqlalchemy.exc.IntegrityError:
|
|
||||||
self.logger.error("SQL Integrity Error on recipe controller action")
|
|
||||||
raise HTTPException(status_code=400, detail=ErrorResponse.respond(message="Recipe already exists"))
|
|
||||||
else:
|
|
||||||
self.logger.error("Unknown Error on recipe controller action")
|
|
||||||
self.logger.exception(ex)
|
|
||||||
raise HTTPException(
|
|
||||||
status_code=500, detail=ErrorResponse.respond(message="Unknown Error", exception=ex.__class__.__name__)
|
|
||||||
)
|
|
||||||
|
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
# URL Scraping Operations
|
# URL Scraping Operations
|
||||||
|
|
||||||
@ -291,11 +270,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@router.post("", status_code=201, response_model=str)
|
@router.post("", status_code=201, response_model=str)
|
||||||
def create_one(self, data: CreateRecipe) -> str | None:
|
def create_one(self, data: CreateRecipe) -> str | None:
|
||||||
"""Takes in a JSON string and loads data into the database as a new entry"""
|
"""Takes in a JSON string and loads data into the database as a new entry"""
|
||||||
try:
|
new_recipe = self.service.create_one(data)
|
||||||
new_recipe = self.service.create_one(data)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if new_recipe:
|
if new_recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
@ -313,10 +288,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@router.post("/{slug}/duplicate", status_code=201, response_model=Recipe)
|
@router.post("/{slug}/duplicate", status_code=201, response_model=Recipe)
|
||||||
def duplicate_one(self, slug: str, req: RecipeDuplicate) -> Recipe:
|
def duplicate_one(self, slug: str, req: RecipeDuplicate) -> Recipe:
|
||||||
"""Duplicates a recipe with a new custom name if given"""
|
"""Duplicates a recipe with a new custom name if given"""
|
||||||
try:
|
new_recipe = self.service.duplicate_one(slug, req)
|
||||||
new_recipe = self.service.duplicate_one(slug, req)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
|
|
||||||
if new_recipe:
|
if new_recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
@ -333,10 +305,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@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."""
|
||||||
try:
|
recipe = self.service.update_one(slug, data)
|
||||||
recipe = self.service.update_one(slug, data)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
|
|
||||||
if recipe:
|
if recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
@ -354,10 +323,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@router.patch("/{slug}")
|
@router.patch("/{slug}")
|
||||||
def patch_one(self, slug: str, data: Recipe):
|
def patch_one(self, slug: str, data: Recipe):
|
||||||
"""Updates a recipe by existing slug and data."""
|
"""Updates a recipe by existing slug and data."""
|
||||||
try:
|
recipe = self.service.patch_one(slug, data)
|
||||||
recipe = self.service.patch_one(slug, data)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
|
|
||||||
if recipe:
|
if recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
@ -375,11 +341,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@router.patch("/{slug}/last-made")
|
@router.patch("/{slug}/last-made")
|
||||||
def update_last_made(self, slug: str, data: RecipeLastMade):
|
def update_last_made(self, slug: str, data: RecipeLastMade):
|
||||||
"""Update a recipe's last made timestamp"""
|
"""Update a recipe's last made timestamp"""
|
||||||
|
recipe = self.service.update_last_made(slug, data.timestamp)
|
||||||
try:
|
|
||||||
recipe = self.service.update_last_made(slug, data.timestamp)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
|
|
||||||
if recipe:
|
if recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
@ -397,10 +359,7 @@ class RecipeController(BaseRecipeController):
|
|||||||
@router.delete("/{slug}")
|
@router.delete("/{slug}")
|
||||||
def delete_one(self, slug: str):
|
def delete_one(self, slug: str):
|
||||||
"""Deletes a recipe by slug"""
|
"""Deletes a recipe by slug"""
|
||||||
try:
|
recipe = self.service.delete_one(slug)
|
||||||
recipe = self.service.delete_one(slug)
|
|
||||||
except Exception as e:
|
|
||||||
self.handle_exceptions(e)
|
|
||||||
|
|
||||||
if recipe:
|
if recipe:
|
||||||
self.publish_event(
|
self.publish_event(
|
||||||
|
@ -30,9 +30,7 @@ class RecipeTimelineEventsController(BaseCrudController):
|
|||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[RecipeTimelineEventCreate, RecipeTimelineEventOut, RecipeTimelineEventUpdate](
|
return HttpRepo[RecipeTimelineEventCreate, RecipeTimelineEventOut, RecipeTimelineEventUpdate](
|
||||||
self.repo,
|
self.repo, self.logger
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_recipe_from_slug(self, slug: str) -> Recipe:
|
def get_recipe_from_slug(self, slug: str) -> Recipe:
|
||||||
|
@ -29,11 +29,7 @@ class IngredientFoodsController(BaseUserController):
|
|||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[SaveIngredientFood, IngredientFood, CreateIngredientFood](
|
return HttpRepo[SaveIngredientFood, IngredientFood, CreateIngredientFood](self.repo, self.logger)
|
||||||
self.repo,
|
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.put("/merge", response_model=SuccessResponse)
|
@router.put("/merge", response_model=SuccessResponse)
|
||||||
def merge_one(self, data: MergeFood):
|
def merge_one(self, data: MergeFood):
|
||||||
|
@ -29,11 +29,7 @@ class IngredientUnitsController(BaseUserController):
|
|||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def mixins(self):
|
def mixins(self):
|
||||||
return HttpRepo[CreateIngredientUnit, IngredientUnit, CreateIngredientUnit](
|
return HttpRepo[CreateIngredientUnit, IngredientUnit, CreateIngredientUnit](self.repo, self.logger)
|
||||||
self.repo,
|
|
||||||
self.logger,
|
|
||||||
self.registered_exceptions,
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.put("/merge", response_model=SuccessResponse)
|
@router.put("/merge", response_model=SuccessResponse)
|
||||||
def merge_one(self, data: MergeUnit):
|
def merge_one(self, data: MergeUnit):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user