api-admim/app/database/TratamentoErros.py

110 lines
4.2 KiB
Python

from fastapi import HTTPException, status
from sqlalchemy.exc import IntegrityError, DataError, OperationalError, TimeoutError
from sqlalchemy.orm.exc import NoResultFound, StaleDataError
class ErrorHandler:
def handle_error(self, exception):
"""
Método principal para tratar exceções do SQLAlchemy e gerar respostas apropriadas.
"""
if isinstance(exception, IntegrityError):
return self.handle_integrity_error(exception)
elif isinstance(exception, DataError):
return self.handle_data_error(exception)
elif isinstance(exception, OperationalError):
return self.handle_operational_error(exception)
elif isinstance(exception, TimeoutError):
return self.handle_timeout_error(exception)
elif isinstance(exception, StaleDataError):
return self.handle_concurrency_error(exception)
elif isinstance(exception, NoResultFound):
return self.handle_no_result_found(exception)
else:
return self.handle_generic_error(exception)
@staticmethod
def handle_integrity_error(exception):
"""
Trata erros de integridade, como violações de chaves únicas ou campos not-null.
"""
if 'not-null constraint' in str(exception.orig):
column_name = str(exception.orig).split('column "')[1].split('"')[0]
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"O campo '{column_name}' não pode ser nulo. Por favor, forneça um valor válido."
)
elif 'unique constraint' in str(exception.orig):
column_name = str(exception.orig).split('constraint "')[1].split('"')[0]
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Violação de unicidade: O valor do campo '{column_name}' "
f"já está em uso. Por favor, use um valor único."
)
else:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Erro de integridade no banco de dados."
)
@staticmethod
def handle_data_error(exception):
"""
Trata erros de dados, como formatação ou valores fora dos limites.
"""
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Erro de dados: {str(exception.orig)}"
)
@staticmethod
def handle_operational_error(exception):
"""
Trata erros de conexão ou operacionais com o banco de dados.
"""
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Erro de conexão com o banco de dados. Por favor, tente novamente mais tarde."
)
@staticmethod
def handle_timeout_error(exception):
"""
Trata erros de timeout em transações com o banco de dados.
"""
raise HTTPException(
status_code=status.HTTP_408_REQUEST_TIMEOUT,
detail="Ocorreu um timeout durante a operação. Por favor, tente novamente."
)
@staticmethod
def handle_concurrency_error(exception):
"""
Trata erros de concorrência quando há múltiplas transações tentando modificar o mesmo dado.
"""
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Erro de concorrência. O dado foi modificado por outra transação."
)
@staticmethod
def handle_no_result_found(exception):
"""
Trata erros de busca sem resultado no banco de dados.
"""
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Nenhum resultado encontrado."
)
@staticmethod
def handle_generic_error(exception):
"""
Trata erros genéricos de SQLAlchemy e gera uma resposta padrão de erro.
"""
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Ocorreu um erro inesperado no banco de dados. Por favor, tente novamente mais tarde."
)