110 lines
4.2 KiB
Python
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."
|
|
)
|