Skip to content

Commit

Permalink
added error handling TODO: docstrings, tests, merge get endpoint #35
Browse files Browse the repository at this point in the history
  • Loading branch information
asuresh-code committed Dec 5, 2024
1 parent a3457c0 commit 3a4fa4e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
48 changes: 46 additions & 2 deletions object_storage_api/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
# TODO: Some of this file is identical to the one in inventory-management-system-api - Use common repo?


from typing import Optional


class BaseAPIException(Exception):
"""
Base exception for API errors.
Expand All @@ -19,17 +22,21 @@ class BaseAPIException(Exception):

detail: str

def __init__(self, detail: str):
def __init__(self, detail: str, response_detail: Optional[str] = None):
"""
Initialise the exception.
:param detail: Specific detail of the exception (just like Exception would take - this will only be logged
and not returned in a response).
:param response_detail: Generic detail of the exception that will be returned in a response.
"""
super().__init__(detail)

self.detail = detail

if response_detail is not None:
self.response_detail = response_detail


class DatabaseError(BaseAPIException):
"""
Expand All @@ -42,9 +49,23 @@ class InvalidObjectIdError(DatabaseError):
The provided value is not a valid ObjectId.
"""

status_code = 422
status_code = 404
response_detail = "Invalid ID given"

def __init__(self, detail: str, response_detail: Optional[str] = None, entity_name: Optional[str] = None):
"""
Initialise the exception.
:param detail: Specific detail of the exception (just like Exception would take - this will only be logged
and not returned in a response).
:param response_detail: Generic detail of the exception to be returned in the response.
:param entity_name: Name of the entity to include in the response detail.
"""
super().__init__(detail, response_detail)

if entity_name is not None:
self.response_detail = f"{entity_name.capitalize()} not found"


class InvalidImageFileError(BaseAPIException):
"""
Expand All @@ -53,3 +74,26 @@ class InvalidImageFileError(BaseAPIException):

status_code = 422
response_detail = "File given is not a valid image"


class MissingRecordError(DatabaseError):
"""
A specific database record was requested but could not be found.
"""

status_code = 404
response_detail = "Requested record was not found"

def __init__(self, detail: str, response_detail: Optional[str] = None, entity_name: Optional[str] = None):
"""
Initialise the exception.
:param detail: Specific detail of the exception (just like Exception would take - this will only be logged
and not returned in a response).
:param response_detail: Generic detail of the exception to be returned in the response.
:param entity_name: Name of the entity to include in the response detail.
"""
super().__init__(detail, response_detail)

if entity_name is not None:
self.response_detail = f"{entity_name.capitalize()} not found"
15 changes: 11 additions & 4 deletions object_storage_api/repositories/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from object_storage_api.core.custom_object_id import CustomObjectId
from object_storage_api.core.database import DatabaseDep
from object_storage_api.core.exceptions import InvalidObjectIdError
from object_storage_api.models.image import ImageIn, ImageOut

logger = logging.getLogger()
Expand Down Expand Up @@ -94,10 +95,16 @@ def update(self, image_id: str, image: ImageIn, session: ClientSession = None) -
"""

logger.info("Updating image metadata with ID: %s", image_id)
image_id = CustomObjectId(image_id)
entity_name = "image"
try:
image_id = CustomObjectId(image_id)
self._images_collection.update_one(
{"_id": image_id}, {"$set": image.model_dump(by_alias=True)}, session=session
)
except InvalidObjectIdError as exc:
raise InvalidObjectIdError(detail=f"Invalid ObjectId value '{image_id}'", entity_name=entity_name) from exc

self._images_collection.update_one(
{"_id": image_id}, {"$set": image.model_dump(by_alias=True)}, session=session
)
image = self.get(image_id=str(image_id), session=session)
if image is None:
raise MissingRecordError(detail=f"No image found with ID: {image_id}", entity_name=entity_name)
return image
2 changes: 1 addition & 1 deletion object_storage_api/services/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def update(self, image_id: str, image: ImagePatchMetadataSchema) -> ImageSchema:
"""
Update an image based on its ID.
:param image_id: The ID of the image to updtae.
:param image_id: The ID of the image to update.
:param image: The new update data for the image.
:return: List of images or an empty list if no images are retrieved.
"""
Expand Down

0 comments on commit 3a4fa4e

Please sign in to comment.