Skip to content

Commit 4fbf12b

Browse files
authored
Fix notification polyfill from incomplete GQL status (#1080)
When connected to a server sending GQL statuses instead of notifications, the driver polyfills `summary.summary_notifications` from the GQL statuses. This PR fixes a but where the driver would ignore any status that was lacking any of the possible fields. However, at least the position is optional and should not cause the status to be swallowed.
1 parent 4acb10f commit 4fbf12b

File tree

2 files changed

+541
-236
lines changed

2 files changed

+541
-236
lines changed

src/neo4j/_work/summary.py

+30-46
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,33 @@ def __getattr__(self, key):
139139
f"'{self.__class__.__name__}' object has no attribute '{key}'"
140140
)
141141

142+
@staticmethod
143+
def _notification_from_status(status: dict) -> dict:
144+
notification = {}
145+
for notification_key, status_key in (
146+
("title", "title"),
147+
("code", "neo4j_code"),
148+
("description", "description"),
149+
):
150+
if status_key in status:
151+
notification[notification_key] = status[status_key]
152+
153+
if "diagnostic_record" in status:
154+
diagnostic_record = status["diagnostic_record"]
155+
if not isinstance(diagnostic_record, dict):
156+
diagnostic_record = {}
157+
158+
for notification_key, diag_record_key in (
159+
("severity", "_severity"),
160+
("category", "_classification"),
161+
("position", "_position"),
162+
):
163+
if diag_record_key in diagnostic_record:
164+
notification[notification_key] = \
165+
diagnostic_record[diag_record_key]
166+
167+
return notification
168+
142169
def _set_notifications(self):
143170
if "notifications" in self.metadata:
144171
notifications = self.metadata["notifications"]
@@ -156,53 +183,10 @@ def _set_notifications(self):
156183
return
157184
notifications = []
158185
for status in statuses:
159-
if not isinstance(status, dict):
160-
continue
161-
notification = {}
162-
failed = False
163-
for notification_key, status_key in (
164-
("title", "title"),
165-
("code", "neo4j_code"),
166-
("description", "description"),
167-
):
168-
value = status.get(status_key)
169-
if not isinstance(value, str) or not value:
170-
failed = True
171-
break
172-
notification[notification_key] = value
173-
if failed:
174-
continue
175-
diagnostic_record = status.get("diagnostic_record")
176-
if not isinstance(diagnostic_record, dict):
177-
continue
178-
for notification_key, diag_record_key in (
179-
("severity", "_severity"),
180-
("category", "_classification"),
181-
):
182-
value = diagnostic_record.get(diag_record_key)
183-
if not isinstance(value, str) or not value:
184-
failed = True
185-
break
186-
notification[notification_key] = value
187-
if failed:
188-
continue
189-
raw_position = diagnostic_record.get("_position")
190-
if not isinstance(raw_position, dict):
191-
continue
192-
position = {}
193-
for pos_key, raw_pos_key in (
194-
("line", "line"),
195-
("column", "column"),
196-
("offset", "offset"),
197-
):
198-
value = raw_position.get(raw_pos_key)
199-
if not isinstance(value, int) or isinstance(value, bool):
200-
failed = True
201-
break
202-
position[pos_key] = value
203-
if failed:
186+
if not (isinstance(status , dict) and "neo4j_code" in status):
187+
# not a notification status
204188
continue
205-
notification["position"] = position
189+
notification = self._notification_from_status(status)
206190
notifications.append(notification)
207191
self.notifications = notifications
208192
return

0 commit comments

Comments
 (0)