This is an automated email from the ASF dual-hosted git repository.

imbajin pushed a commit to branch goal-test
in repository https://gitbox.apache.org/repos/asf/hugegraph-ai.git

commit 984208d79c16c1c6432fd886380a0b19c57b3a39
Author: imbajin <[email protected]>
AuthorDate: Sun May 31 12:22:58 2026 +0800

    fix(client): preserve unauthorized response type
    
    - restore NotAuthorizedError handling in ResponseValidation
    - remove dead HTTPError fallback branch
    - add regression coverage for 401 responses
    - record the production change in quality ledgers
---
 .workflow/quality-program/reports/final-quality-report.md |  3 ++-
 .../quality-program/reports/production-change-ledger.md   |  1 +
 hugegraph-python-client/src/pyhugegraph/utils/util.py     |  7 ++++---
 .../src/tests/api/test_response_validation.py             | 15 +++++++++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/.workflow/quality-program/reports/final-quality-report.md 
b/.workflow/quality-program/reports/final-quality-report.md
index 09b8d1fa..2906638e 100644
--- a/.workflow/quality-program/reports/final-quality-report.md
+++ b/.workflow/quality-program/reports/final-quality-report.md
@@ -77,8 +77,9 @@ Final G7 sanity checks:
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Extend primary-key endpoint mapping to multi-key vertex labels. | `uv run 
pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph_load_into_graph.py
 -q` |
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` |
 | PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` |
+| PR68 second review | `hugegraph-python-client/src/pyhugegraph/utils/util.py` 
| Preserve `NotAuthorizedError` for 401 responses in `ResponseValidation`. | 
`uv run pytest 
hugegraph-python-client/src/tests/api/test_response_validation.py -q` |
 
-No production code changed in G5-G7. PR68 review fixes added the two 
production-code rows above.
+No production code changed in G5-G7. PR68 review fixes added the 
production-code rows above.
 
 ## Failures, Skips, and Known Risks
 
diff --git a/.workflow/quality-program/reports/production-change-ledger.md 
b/.workflow/quality-program/reports/production-change-ledger.md
index 35b9b9d3..5684375a 100644
--- a/.workflow/quality-program/reports/production-change-ledger.md
+++ b/.workflow/quality-program/reports/production-change-ledger.md
@@ -8,3 +8,4 @@
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Extend primary-key endpoint mapping to multi-key vertex labels by joining 
primary key values with `!`. | `uv run pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph_load_into_graph.py
 -q` | Review-identified edge creation gap for multiple primary-key vertex IDs. 
| Low; only broadens fallback mapping for existing primary-key schemas. |
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` | Avoid 
import-time cwd mutation in test harness and make config path deterministic. | 
Medium-low; preserves the same file path when run from module root and removes 
cwd guard. |
 | PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` | Avoid writing or 
reading a caller cwd `.env` when tests import config from repo root. | 
Medium-low; preserves the same `.env` file when run from module root and 
removes cwd coupling. |
+| PR68 second review | `hugegraph-python-client/src/pyhugegraph/utils/util.py` 
| Preserve `NotAuthorizedError` for 401 responses in `ResponseValidation` while 
keeping backend error-envelope details for other HTTP errors. | `uv run pytest 
hugegraph-python-client/src/tests/api/test_response_validation.py -q` | 
Second-review finding that the G2 envelope preservation broadened 401 responses 
to generic `Exception`. | Low; restores the existing 401 contract and removes 
dead HTTPError fallback code. |
diff --git a/hugegraph-python-client/src/pyhugegraph/utils/util.py 
b/hugegraph-python-client/src/pyhugegraph/utils/util.py
index c1b806cb..ffe0ff90 100644
--- a/hugegraph-python-client/src/pyhugegraph/utils/util.py
+++ b/hugegraph-python-client/src/pyhugegraph/utils/util.py
@@ -100,6 +100,9 @@ class ResponseValidation:
             if not self._strict and response.status_code == 404:
                 log.info("Resource %s not found (404)", path)
             else:
+                if response.status_code == 401:
+                    check_if_authorized(response)
+
                 try:
                     body = response.json()
                     if isinstance(body, dict):
@@ -129,9 +132,7 @@ class ResponseValidation:
 
                 if response.status_code == 404:
                     raise NotFoundError(response.content) from e
-                if response.status_code >= 400:
-                    raise Exception(f"Server Exception: {details}") from e
-                raise e
+                raise Exception(f"Server Exception: {details}") from e
 
         except Exception:  # pylint: disable=broad-exception-caught
             log.error("Unhandled exception occurred: %s", 
traceback.format_exc())
diff --git a/hugegraph-python-client/src/tests/api/test_response_validation.py 
b/hugegraph-python-client/src/tests/api/test_response_validation.py
index c66a2086..77dc3c9a 100644
--- a/hugegraph-python-client/src/tests/api/test_response_validation.py
+++ b/hugegraph-python-client/src/tests/api/test_response_validation.py
@@ -20,6 +20,7 @@ from unittest.mock import Mock
 
 import pytest
 import requests
+from pyhugegraph.utils.exceptions import NotAuthorizedError
 from pyhugegraph.utils.util import ResponseValidation
 
 pytestmark = pytest.mark.contract
@@ -77,6 +78,20 @@ class TestResponseValidation(unittest.TestCase):
         with self.assertRaisesRegex(Exception, "Server Exception: not json"):
             validator(response, "POST", "/gremlin")
 
+    def test_unauthorized_error_preserves_not_authorized_type(self):
+        response = Mock(spec=requests.Response)
+        response.status_code = 401
+        response.text = 
'{"exception":"NotAuthorizedException","message":"Authentication failed"}'
+        response.content = response.text.encode("utf-8")
+        response.request = Mock(body="Empty body", 
url="http://127.0.0.1:8080/graphs";)
+        response.raise_for_status.side_effect = 
requests.exceptions.HTTPError("401 Client Error")
+        validator = ResponseValidation()
+
+        with pytest.raises(NotAuthorizedError) as exc_info:
+            validator(response, method="GET", path="/graphs")
+
+        assert "Please check your username and password" in str(exc_info.value)
+
 
 if __name__ == "__main__":
     unittest.main()

Reply via email to