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." )