Skip to content

Commit 154054b

Browse files
authored
[4.4] Improve Noe4jError representation (#805)
* 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 51fd4a4 commit 154054b

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
@@ -146,14 +146,16 @@ def is_fatal_during_discovery(self):
146146
return False
147147

148148
def __str__(self):
149-
return "{{code: {code}}} {{message: {message}}}".format(code=self.code, message=self.message)
149+
if self.code or self.message:
150+
return "{{code: {code}}} {{message: {message}}}".format(
151+
code=self.code, message=self.message
152+
)
153+
return super().__str__()
150154

151155

152156
class ClientError(Neo4jError):
153157
""" The Client sent a bad request - changing the request might yield a successful outcome.
154158
"""
155-
def __str__(self):
156-
return super(Neo4jError, self).__str__()
157159

158160

159161
class DatabaseError(Neo4jError):

tests/unit/test_exceptions.py

+56
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,59 @@ def test_transient_error_is_retriable_case_3():
237237

238238
assert isinstance(error, TransientError)
239239
assert error.is_retriable() is True
240+
241+
242+
@pytest.mark.parametrize(
243+
("code", "message", "expected_cls", "expected_str"),
244+
(
245+
(
246+
"Neo.ClientError.General.UnknownError",
247+
"Test error message",
248+
ClientError,
249+
"{code: Neo.ClientError.General.UnknownError} "
250+
"{message: Test error message}"
251+
),
252+
(
253+
None,
254+
"Test error message",
255+
DatabaseError,
256+
"{code: Neo.DatabaseError.General.UnknownError} "
257+
"{message: Test error message}"
258+
),
259+
(
260+
"",
261+
"Test error message",
262+
DatabaseError,
263+
"{code: Neo.DatabaseError.General.UnknownError} "
264+
"{message: Test error message}"
265+
),
266+
(
267+
"Neo.ClientError.General.UnknownError",
268+
None,
269+
ClientError,
270+
"{code: Neo.ClientError.General.UnknownError} "
271+
"{message: An unknown error occurred}"
272+
),
273+
(
274+
"Neo.ClientError.General.UnknownError",
275+
"",
276+
ClientError,
277+
"{code: Neo.ClientError.General.UnknownError} "
278+
"{message: An unknown error occurred}"
279+
),
280+
)
281+
)
282+
def test_neo4j_error_from_server_as_str(code, message, expected_cls,
283+
expected_str):
284+
error = Neo4jError.hydrate(code=code, message=message)
285+
286+
assert type(error) == expected_cls
287+
assert str(error) == expected_str
288+
289+
290+
@pytest.mark.parametrize("cls", (Neo4jError, ClientError))
291+
def test_neo4j_error_from_code_as_str(cls):
292+
error = cls("Generated somewhere in the driver")
293+
294+
assert type(error)== cls
295+
assert str(error) == "Generated somewhere in the driver"

0 commit comments

Comments
 (0)