Skip to content

Commit

Permalink
Merge branch 'master' into HAN-91
Browse files Browse the repository at this point in the history
  • Loading branch information
fjpacheco committed Apr 20, 2024
2 parents 5664feb + c4cda52 commit 0f2e706
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 5 deletions.
3 changes: 1 addition & 2 deletions app/exceptions/UserException.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def __init__(self):


class InvalidURL(HTTPException):
def __init__(self, id: int):
def __init__(self, detail: str):
status_code = status.HTTP_400_BAD_REQUEST
detail = "Invalid URL"
super().__init__(status_code=status_code, detail=detail)
2 changes: 1 addition & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

@app.get("/")
def root():
return {"message": "Hello World"}
return {"message": "users service"}


@app.get("/users/{user_id}")
Expand Down
6 changes: 6 additions & 0 deletions app/repository/Users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from models.database import Base
from models.users import User
from datetime import date
from .sql_exception_handling import withSQLExceptionsHandle


class UsersRepository:
Expand All @@ -25,14 +26,17 @@ def shutdown(self):
def rollback(self):
self.session.rollback()

@withSQLExceptionsHandle()
def add(self, record: Base):
self.session.add(record)
self.session.commit()

@withSQLExceptionsHandle()
def get_user(self, user_id: int):
user = self.session.query(User).filter_by(id=user_id).first()
return user.__dict__ if user else None

@withSQLExceptionsHandle()
def get_user_by_email(self, email: str):
user = self.session.query(User).filter_by(email=email).first()
return user.__dict__ if user else None
Expand All @@ -45,6 +49,7 @@ def get_users_by_ids(self, ids: list):
users = self.session.query(User).filter(User.id.in_(ids)).all()
return self.__parse_result(users)

@withSQLExceptionsHandle()
def create_user(
self,
email: str,
Expand Down Expand Up @@ -78,6 +83,7 @@ def create_user(
self.session.commit()
return new_user

@withSQLExceptionsHandle()
def edit_user(self, user_id: int, data_to_edit: dict):
user = self.session.query(User).filter_by(id=user_id).first()
for field, value in data_to_edit.items():
Expand Down
59 changes: 59 additions & 0 deletions app/repository/sql_exception_handling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from psycopg2.errors import UniqueViolation
from sqlalchemy.exc import PendingRollbackError, IntegrityError, NoResultFound
from fastapi import status, HTTPException
import logging

logger = logging.getLogger("app")
logger.setLevel("DEBUG")


def handle_common_errors(err):
if isinstance(err, IntegrityError):
if isinstance(err.orig, UniqueViolation):
parsed_error = err.orig.pgerror.split("\n")
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={
"error": parsed_error[0],
"detail": parsed_error[1]
})

raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=format(err))

if isinstance(err, PendingRollbackError):
logger.warning(format(err))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=format(err)
)

if isinstance(err, NoResultFound):
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail=format(err)
)

logger.error(format(err))
raise err


def withSQLExceptionsHandle(async_mode: bool = False):
def decorator(func):
async def handleAsyncSQLException(*args, **kwargs):
try:
return await func(*args, **kwargs)
except Exception as err:
return handle_common_errors(err)

def handleSyncSQLException(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as err:
return handle_common_errors(err)

return (
handleAsyncSQLException if async_mode else handleSyncSQLException
)

return decorator
13 changes: 11 additions & 2 deletions app/service/Users.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ def get_users_by_ids(self, ids: list):
def create_user(self, user_data: dict):
if not self._validate_location(user_data.get("location")):
raise InvalidData()
return self.user_repository.create_user(**user_data)
try:
user = self.user_repository.create_user(**user_data)
return user
except Exception as e:
self.user_repository.rollback()
raise e

def update_user(self, user_id: int, update_data: dict):
# TODO: aca habria que chequear a partir del token, session o algo que
Expand All @@ -41,7 +46,11 @@ def update_user(self, user_id: int, update_data: dict):
if not re.match(r'^https?://(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}'
r'(?:/[^/#?]+)+(?:\?.*)?$', photo_url):
raise InvalidURL("Invalid photo URL")
self.user_repository.edit_user(user_id, filtered_update_data)
try:
self.user_repository.edit_user(user_id, filtered_update_data)
except Exception as e:
self.user_repository.rollback()
raise e

def login(self, auth_code: str):
access_token = self._get_access_token(auth_code)
Expand Down

0 comments on commit 0f2e706

Please sign in to comment.