Skip to content

Commit fdcbe2e

Browse files
navjots18Navjot SinghNavjot Singhblink1073
authored
PYTHON-1982 Update Invalid Document error message to include doc (#1854)
Co-authored-by: Navjot Singh <navjot@Navjots-Air.station> Co-authored-by: Navjot Singh <navjot@Navjots-MacBook-Air.local> Co-authored-by: Steven Silvester <steven.silvester@ieee.org>
1 parent f45b35a commit fdcbe2e

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

bson/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,10 @@ def _dict_to_bson(
10061006
elements.append(_name_value_to_bson(b"_id\x00", doc["_id"], check_keys, opts))
10071007
for key, value in doc.items():
10081008
if not top_level or key != "_id":
1009-
elements.append(_element_to_bson(key, value, check_keys, opts))
1009+
try:
1010+
elements.append(_element_to_bson(key, value, check_keys, opts))
1011+
except InvalidDocument as err:
1012+
raise InvalidDocument(f"Invalid document {doc} | {err}") from err
10101013
except AttributeError:
10111014
raise TypeError(f"encoder expected a mapping type but got: {doc!r}") from None
10121015

bson/_cbsonmodule.c

+35
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,41 @@ int write_dict(PyObject* self, buffer_t buffer,
17431743
while (PyDict_Next(dict, &pos, &key, &value)) {
17441744
if (!decode_and_write_pair(self, buffer, key, value,
17451745
check_keys, options, top_level)) {
1746+
if (PyErr_Occurred()) {
1747+
PyObject *etype = NULL, *evalue = NULL, *etrace = NULL;
1748+
PyErr_Fetch(&etype, &evalue, &etrace);
1749+
PyObject *InvalidDocument = _error("InvalidDocument");
1750+
1751+
if (top_level && InvalidDocument && PyErr_GivenExceptionMatches(etype, InvalidDocument)) {
1752+
1753+
Py_DECREF(etype);
1754+
etype = InvalidDocument;
1755+
1756+
if (evalue) {
1757+
PyObject *msg = PyObject_Str(evalue);
1758+
Py_DECREF(evalue);
1759+
1760+
if (msg) {
1761+
// Prepend doc to the existing message
1762+
PyObject *dict_str = PyObject_Str(dict);
1763+
PyObject *new_msg = PyUnicode_FromFormat("Invalid document %s | %s", PyUnicode_AsUTF8(dict_str), PyUnicode_AsUTF8(msg));
1764+
Py_DECREF(dict_str);
1765+
1766+
if (new_msg) {
1767+
evalue = new_msg;
1768+
}
1769+
else {
1770+
evalue = msg;
1771+
}
1772+
}
1773+
}
1774+
PyErr_NormalizeException(&etype, &evalue, &etrace);
1775+
}
1776+
else {
1777+
Py_DECREF(InvalidDocument);
1778+
}
1779+
PyErr_Restore(etype, evalue, etrace);
1780+
}
17461781
return 0;
17471782
}
17481783
}

doc/contributors.rst

+1
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,4 @@ The following is a list of people who have contributed to
102102
- Ivan Lukyanchikov (ilukyanchikov)
103103
- Terry Patterson
104104
- Romain Morotti
105+
- Navjot Singh (navjots18)

test/test_bson.py

+13
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,19 @@ def __repr__(self):
10991099
):
11001100
encode({"t": Wrapper(1)})
11011101

1102+
def test_doc_in_invalid_document_error_message(self):
1103+
class Wrapper:
1104+
def __init__(self, val):
1105+
self.val = val
1106+
1107+
def __repr__(self):
1108+
return repr(self.val)
1109+
1110+
self.assertEqual("1", repr(Wrapper(1)))
1111+
doc = {"t": Wrapper(1)}
1112+
with self.assertRaisesRegex(InvalidDocument, f"Invalid document {doc}"):
1113+
encode(doc)
1114+
11021115

11031116
class TestCodecOptions(unittest.TestCase):
11041117
def test_document_class(self):

0 commit comments

Comments
 (0)