From a2e5671921b374fe93268f07edead0d2b6e5d9e6 Mon Sep 17 00:00:00 2001 From: Florian Spreckelsen <f.spreckelsen@indiscale.com> Date: Thu, 12 Dec 2024 11:25:55 +0100 Subject: [PATCH 1/4] TST: Add test for https://gitlab.com/linkahead/linkahead-pylib/-/issues/87 --- unittests/test_error_handling.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/unittests/test_error_handling.py b/unittests/test_error_handling.py index 3f524146..c7325341 100644 --- a/unittests/test_error_handling.py +++ b/unittests/test_error_handling.py @@ -30,7 +30,7 @@ import linkahead as db from linkahead.common.models import raise_errors from linkahead.exceptions import (AuthorizationError, EntityDoesNotExistError, EntityError, - EntityHasNoDatatypeError, + EntityHasNoDatatypeError, HTTPServerError, TransactionError, UniqueNamesError, UnqualifiedParentsError, UnqualifiedPropertiesError) @@ -315,3 +315,9 @@ def test_container_with_faulty_elements(): # record raises both of them assert (isinstance(err, UnqualifiedParentsError) or isinstance(err, UnqualifiedPropertiesError)) + + +def test_incomplete_server_error_response(): + """The reason behind https://gitlab.com/linkahead/linkahead-pylib/-/issues/87.""" + err = HTTPServerError("Bla") + assert str(err) == "Bla" -- GitLab From 4d6d1c8619d3e72dc3b87e1e05b4b318d849526b Mon Sep 17 00:00:00 2001 From: Florian Spreckelsen <f.spreckelsen@indiscale.com> Date: Thu, 12 Dec 2024 11:40:58 +0100 Subject: [PATCH 2/4] TST: extend tests for https://gitlab.com/linkahead/linkahead-pylib/-/issues/87 --- unittests/test_error_handling.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/unittests/test_error_handling.py b/unittests/test_error_handling.py index c7325341..64f743c8 100644 --- a/unittests/test_error_handling.py +++ b/unittests/test_error_handling.py @@ -319,5 +319,22 @@ def test_container_with_faulty_elements(): def test_incomplete_server_error_response(): """The reason behind https://gitlab.com/linkahead/linkahead-pylib/-/issues/87.""" + # Case 1: Response is no XML at all err = HTTPServerError("Bla") assert str(err) == "Bla" + + # Case 2: Response is an incomplete XML, e.g. due to very unlucky timeout + err = HTTPServerError("<incomplete>XML</inc") + assert str(err) == "<incomplete>XML</inc" + + # Case 3: Response is complete XML but doesn't have response and or error information + err = HTTPServerError("<complete>XML</complete>") + assert str(err) == "<complete>XML</complete>" + + # Case 4: Response is an XML response but the error is lacking a description + err = HTTPServerError("<Response><Error>complete error</Error></Response>") + assert str(err) == "complete error" + + # Case 5: Healthy error Response + err = HTTPServerError("<Response><Error description='Error'>complete error</Error></Response>") + assert str(err) == "Error\n\ncomplete error" -- GitLab From 8883815a4a7a16c8ef1ed333bcee1fa8f79629fa Mon Sep 17 00:00:00 2001 From: Florian Spreckelsen <f.spreckelsen@indiscale.com> Date: Thu, 12 Dec 2024 11:41:19 +0100 Subject: [PATCH 3/4] BUG: Fix https://gitlab.com/linkahead/linkahead-pylib/-/issues/87 --- src/linkahead/exceptions.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/linkahead/exceptions.py b/src/linkahead/exceptions.py index 609d3654..7d4dc085 100644 --- a/src/linkahead/exceptions.py +++ b/src/linkahead/exceptions.py @@ -94,12 +94,26 @@ class HTTPServerError(LinkAheadException): """HTTPServerError represents 5xx HTTP server errors.""" def __init__(self, body): - xml = etree.fromstring(body) - error = xml.xpath('/Response/Error')[0] - msg = error.get("description") - - if error.text is not None: - msg = msg + "\n\n" + error.text + try: + # This only works if the server sends a valid XML + # response. Then it can be parsed for more information. + xml = etree.fromstring(body) + if xml.xpath('/Response/Error'): + error = xml.xpath('/Response/Error')[0] + msg = error.get("description") if error.get("description") is not None else "" + + if error.text is not None: + if msg: + msg = msg + "\n\n" + error.text + else: + msg = error.text + else: + # Valid XML, but no error information + msg = body + except etree.XMLSyntaxError: + # Handling of incomplete responses, e.g., due to timeouts, + # c.f. https://gitlab.com/linkahead/linkahead-pylib/-/issues/87. + msg = body LinkAheadException.__init__(self, msg) -- GitLab From 84443119172283b71f60a3516784a2595a06e69a Mon Sep 17 00:00:00 2001 From: Florian Spreckelsen <f.spreckelsen@indiscale.com> Date: Thu, 12 Dec 2024 12:02:38 +0100 Subject: [PATCH 4/4] DOC: Update Changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 928c5230..e1fd615a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `authentication/interface/on_response()` does not overwrite `auth_token` if new value is `None` * [#119](https://gitlab.com/linkahead/linkahead-pylib/-/issues/119) - The diff returned by compare_entities now uses id instead of name as key if either property does not have a name + The diff returned by compare_entities now uses id instead of name as + key if either property does not have a name +* [#87](https://gitlab.com/linkahead/linkahead-pylib/-/issues/87) + `XMLSyntaxError` messages when parsing (incomplete) responses in + case of certain connection timeouts. ### Security ### -- GitLab