diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ad0c304..49b3ebf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Added `py.typed` markers +- Fixed semantic error handling ## [4.6.1] - 2024-09-30 diff --git a/azure-kusto-data/azure/kusto/data/exceptions.py b/azure-kusto-data/azure/kusto/data/exceptions.py index d4afd1ad..134affbb 100644 --- a/azure-kusto-data/azure/kusto/data/exceptions.py +++ b/azure-kusto-data/azure/kusto/data/exceptions.py @@ -27,6 +27,9 @@ class KustoTokenParsingError(KustoStreamingQueryError): ... +SEMANTIC_ERROR_STRING = "Semantic error:" + + class KustoServiceError(KustoError): """Raised when the Kusto service was unable to process a request.""" @@ -40,6 +43,8 @@ def __init__( self.http_response = http_response self.kusto_response = kusto_response + self.message_text = messages if isinstance(messages, str) else "\n\n".join(repr(m) for m in messages) + def get_raw_http_response(self) -> "Union[requests.Response, ClientResponse, None]": """Gets the http response.""" return self.http_response @@ -47,7 +52,7 @@ def get_raw_http_response(self) -> "Union[requests.Response, ClientResponse, Non def is_semantic_error(self) -> bool: """Checks if a response is a semantic error.""" try: - return "Semantic error:" in self.http_response.text + return SEMANTIC_ERROR_STRING in self.message_text except AttributeError: return False diff --git a/azure-kusto-data/tests/test_e2e_data.py b/azure-kusto-data/tests/test_e2e_data.py index e2c445d0..f2bce2a4 100644 --- a/azure-kusto-data/tests/test_e2e_data.py +++ b/azure-kusto-data/tests/test_e2e_data.py @@ -386,3 +386,16 @@ async def test_no_redirects_fail_in_client_async(self, code): with pytest.raises(KustoServiceError) as ex: await client.execute("db", "table") assert ex.value.http_response.status == code + + def test_semantic_error(self): + with self.get_client() as client: + with pytest.raises(KustoServiceError) as ex: + client.execute(self.test_db, "Nonexistent") + assert ex.value.is_semantic_error() + + @pytest.mark.asyncio + async def test_semantic_error_async(self): + async with await self.get_async_client() as client: + with pytest.raises(KustoServiceError) as ex: + await client.execute(self.test_db, "Nonexistent") + assert ex.value.is_semantic_error()