Skip to content

Commit 018b0b8

Browse files
authored
Improve Noe4jError representation (#806)
* Improve Noe4jError representation When the error is not received from the DBMS, but instead originates from somewhere in the driver, it might not have a code and a message. In that case, we fall back to the default Exception representation. Related: * #796 * Make Neo4jError representation more robust Even though, all errors that come from the server go through `Noej4jError.hydrate` which (currently) makes sure that `code` *and* `message` are set, this might change in the future.
1 parent 0cf6741 commit 018b0b8

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

neo4j/exceptions.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,17 @@ def is_fatal_during_discovery(self) -> bool:
247247
return False
248248

249249
def __str__(self):
250-
return "{{code: {code}}} {{message: {message}}}".format(code=self.code, message=self.message)
250+
if self.code or self.message:
251+
return "{{code: {code}}} {{message: {message}}}".format(
252+
code=self.code, message=self.message
253+
)
254+
return super().__str__()
251255

252256

253257
# Neo4jError > ClientError
254258
class ClientError(Neo4jError):
255259
""" The Client sent a bad request - changing the request might yield a successful outcome.
256260
"""
257-
def __str__(self) -> str:
258-
return super().__str__()
259261

260262

261263
# Neo4jError > ClientError > CypherSyntaxError

tests/unit/common/test_exceptions.py

+56
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,59 @@ def test_error_rewrite(code, expected_cls, expected_code):
257257
assert error.is_retryable() is expected_retryable
258258
with pytest.warns(DeprecationWarning, match=".*is_retryable.*"):
259259
assert error.is_retriable() is expected_retryable
260+
261+
262+
@pytest.mark.parametrize(
263+
("code", "message", "expected_cls", "expected_str"),
264+
(
265+
(
266+
"Neo.ClientError.General.UnknownError",
267+
"Test error message",
268+
ClientError,
269+
"{code: Neo.ClientError.General.UnknownError} "
270+
"{message: Test error message}"
271+
),
272+
(
273+
None,
274+
"Test error message",
275+
DatabaseError,
276+
"{code: Neo.DatabaseError.General.UnknownError} "
277+
"{message: Test error message}"
278+
),
279+
(
280+
"",
281+
"Test error message",
282+
DatabaseError,
283+
"{code: Neo.DatabaseError.General.UnknownError} "
284+
"{message: Test error message}"
285+
),
286+
(
287+
"Neo.ClientError.General.UnknownError",
288+
None,
289+
ClientError,
290+
"{code: Neo.ClientError.General.UnknownError} "
291+
"{message: An unknown error occurred}"
292+
),
293+
(
294+
"Neo.ClientError.General.UnknownError",
295+
"",
296+
ClientError,
297+
"{code: Neo.ClientError.General.UnknownError} "
298+
"{message: An unknown error occurred}"
299+
),
300+
)
301+
)
302+
def test_neo4j_error_from_server_as_str(code, message, expected_cls,
303+
expected_str):
304+
error = Neo4jError.hydrate(code=code, message=message)
305+
306+
assert type(error) == expected_cls
307+
assert str(error) == expected_str
308+
309+
310+
@pytest.mark.parametrize("cls", (Neo4jError, ClientError))
311+
def test_neo4j_error_from_code_as_str(cls):
312+
error = cls("Generated somewhere in the driver")
313+
314+
assert type(error)== cls
315+
assert str(error) == "Generated somewhere in the driver"

0 commit comments

Comments
 (0)