From ef577ac5eb1a8c4a54820646b02b26e3cd6dbf4b Mon Sep 17 00:00:00 2001 From: Johannes Nussbaum <39048939+jnussbaum@users.noreply.github.com> Date: Thu, 1 Feb 2024 08:01:59 +0100 Subject: [PATCH] fix(xmlupload): don't retry on OntologyConstraintException (DEV-3255) (#783) --- src/dsp_tools/commands/xmlupload/xmlupload.py | 2 ++ src/dsp_tools/utils/connection_live.py | 7 ++++++- test/unittests/utils/test_connection_live.py | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dsp_tools/commands/xmlupload/xmlupload.py b/src/dsp_tools/commands/xmlupload/xmlupload.py index bcef25f03..fbe1d7079 100644 --- a/src/dsp_tools/commands/xmlupload/xmlupload.py +++ b/src/dsp_tools/commands/xmlupload/xmlupload.py @@ -130,6 +130,8 @@ def xmlupload( logger.info("All resources have successfully been uploaded.") else: print(f"\n{datetime.now()}: WARNING: Could not upload the following resources: {failed_uploads}\n") + logfiles = ", ".join([handler.baseFilename for handler in logger.handlers if isinstance(handler, FileHandler)]) + print(f"For more information, see the log file: {logfiles}\n") logger.warning(f"Could not upload the following resources: {failed_uploads}") return success diff --git a/src/dsp_tools/utils/connection_live.py b/src/dsp_tools/utils/connection_live.py index fcc7ad635..fc03eb5ff 100644 --- a/src/dsp_tools/utils/connection_live.py +++ b/src/dsp_tools/utils/connection_live.py @@ -5,6 +5,7 @@ from datetime import datetime from functools import partial from importlib.metadata import version +from logging import FileHandler from typing import Any, Literal, Optional, cast import regex @@ -251,6 +252,7 @@ def _try_network_action(self, params: RequestParameters) -> Response: Returns: the return value of action """ + logfiles = ", ".join([handler.baseFilename for handler in logger.handlers if isinstance(handler, FileHandler)]) action = partial(self.session.request, **params.as_kwargs()) for i in range(7): try: @@ -269,11 +271,14 @@ def _try_network_action(self, params: RequestParameters) -> Response: return response elif "v2/authentication" in params.url and response.status_code == HTTP_UNAUTHORIZED: raise BadCredentialsError("Bad credentials") + elif "OntologyConstraintException" in response.text: + msg = f"Permanently unable to execute the network action. See logs for more details: {logfiles}" + raise PermanentConnectionError(msg) elif not self._in_testing_environment(): self._log_and_sleep(reason="Non-200 response code", retry_counter=i, exc_info=False) continue else: - msg = "Permanently unable to execute the network action. See logs for more details." + msg = f"Permanently unable to execute the network action. See logs for more details: {logfiles}" raise PermanentConnectionError(msg) # after 7 vain attempts to create a response, try it a last time and let it escalate diff --git a/test/unittests/utils/test_connection_live.py b/test/unittests/utils/test_connection_live.py index 31d0822c9..a19b0f644 100644 --- a/test/unittests/utils/test_connection_live.py +++ b/test/unittests/utils/test_connection_live.py @@ -290,7 +290,7 @@ def test_try_network_action_connection_error(monkeypatch: pytest.MonkeyPatch) -> def test_try_network_action_non_200(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.delenv("DSP_TOOLS_TESTING", raising=False) # in CI, this variable suppresses the retrying mechanism con = ConnectionLive("http://example.com/") - responses = (Mock(status_code=500), Mock(status_code=404), Mock(status_code=200)) + responses = (Mock(status_code=500, text=""), Mock(status_code=404, text=""), Mock(status_code=200, text="")) session_mock = SessionMock(responses) con.session = session_mock # type: ignore[assignment] con._log_request = Mock() @@ -307,7 +307,7 @@ def test_try_network_action_non_200(monkeypatch: pytest.MonkeyPatch) -> None: def test_try_network_action_in_testing_environment(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("DSP_TOOLS_TESTING", "true") # automatically set in CI, but not locally con = ConnectionLive("http://example.com/") - responses = (Mock(status_code=500), Mock(status_code=404), Mock(status_code=200)) + responses = (Mock(status_code=500, text=""), Mock(status_code=404, text=""), Mock(status_code=200, text="")) con.session = SessionMock(responses) # type: ignore[assignment] con._log_request = Mock() con._log_response = Mock()