Skip to content

Commit 5c6fc58

Browse files
Navjot SinghNavjot Singh
authored andcommitted
Updated Invalid Document error message to have doc
1 parent c883012 commit 5c6fc58

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

bson/__init__.py

Lines changed: 4 additions & 1 deletion
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("Invalid document {} | {}".format(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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,45 @@ 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, *evalue, *etrace;
1748+
PyErr_Fetch(&etype, &evalue, &etrace);
1749+
PyObject *InvalidDocument = _error("InvalidDocument");
1750+
1751+
if (PyErr_GivenExceptionMatches(etype, InvalidDocument)) {
1752+
1753+
if (InvalidDocument) {
1754+
Py_DECREF(etype);
1755+
etype = InvalidDocument;
1756+
1757+
if (evalue) {
1758+
PyObject *msg = PyObject_Str(evalue);
1759+
Py_DECREF(evalue);
1760+
1761+
if (msg) {
1762+
// Prepend doc to the existing message
1763+
PyObject *dict_str = PyObject_Str(dict);
1764+
PyObject *new_msg = PyUnicode_FromFormat("Invalid document %s | %s", PyUnicode_AsUTF8(dict_str), PyUnicode_AsUTF8(msg));
1765+
Py_DECREF(dict_str);
1766+
1767+
if (new_msg) {
1768+
evalue = new_msg;
1769+
Py_DECREF(new_msg);
1770+
}
1771+
else{
1772+
evalue = msg;
1773+
}
1774+
1775+
Py_DECREF(msg);
1776+
1777+
}
1778+
}
1779+
PyErr_NormalizeException(&etype, &evalue, &etrace);
1780+
}
1781+
}
1782+
PyErr_Restore(etype, evalue, etrace);
1783+
Py_DECREF(InvalidDocument);
1784+
}
17461785
return 0;
17471786
}
17481787
}

test/test_bson.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,22 @@ def __repr__(self):
10001000
):
10011001
encode({"t": Wrapper(1)})
10021002

1003+
def test_doc_in_invalid_document_error_message(self):
1004+
1005+
class Wrapper:
1006+
def __init__(self, val):
1007+
self.val = val
1008+
1009+
def __repr__(self):
1010+
return repr(self.val)
1011+
1012+
self.assertEqual("1", repr(Wrapper(1)))
1013+
doc = {"t": Wrapper(1)}
1014+
with self.assertRaisesRegex(
1015+
InvalidDocument, "Invalid document {}".format(doc)
1016+
):
1017+
encode(doc)
1018+
10031019

10041020
class TestCodecOptions(unittest.TestCase):
10051021
def test_document_class(self):

0 commit comments

Comments
 (0)