Repository: MongoEngine/mongoengine

Issue:
Print queryset fails with a vague error
The following fails to print in python3. Note that is_active is of type mongoengine.BooleanField

`user_details = Users.objects.filter(is_active=True)`
`print("users details", user_details)`

The error is:
`mongoengine.errors.InvalidDocumentError: Invalid data to create a `Users` instance.
type - The source SON object needs to be of type 'dict'
`


Discussion:
I agree that the error is unclear at first sight but it isn't due to `is_active=True` at all, the error you get is due to a discrepancy between your model definition and one of the existing document that doesn't match the format (In this case one of the existing document has a `type` field that has a weird shape, its expected to be a `dict`/EMbeddedDocument but something else was found.

I'll keep this ticket opened as the message can be improved

Resolving patch:
diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py
--- a/mongoengine/base/document.py
+++ b/mongoengine/base/document.py
@@ -732,7 +732,10 @@ def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False)
             only_fields = []
 
         if son and not isinstance(son, dict):
-            raise ValueError("The source SON object needs to be of type 'dict'")
+            raise ValueError(
+                "The source SON object needs to be of type 'dict' but a '%s' was found"
+                % type(son)
+            )
 
         # Get the class name from the document, falling back to the given
         # class if unavailable
@@ -770,7 +773,9 @@ def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False)
                     errors_dict[field_name] = e
 
         if errors_dict:
-            errors = "\n".join(["%s - %s" % (k, v) for k, v in errors_dict.items()])
+            errors = "\n".join(
+                ["Field '%s' - %s" % (k, v) for k, v in errors_dict.items()]
+            )
             msg = "Invalid data to create a `%s` instance.\n%s" % (
                 cls._class_name,
                 errors,


Test patch:
diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py
--- a/tests/document/test_instance.py
+++ b/tests/document/test_instance.py
@@ -3656,6 +3656,32 @@ class User(Document):
         with self.assertRaises(DuplicateKeyError):
             User.objects().select_related()
 
+    def test_embedded_document_failed_while_loading_instance_when_it_is_not_a_dict(
+        self
+    ):
+        class LightSaber(EmbeddedDocument):
+            color = StringField()
+
+        class Jedi(Document):
+            light_saber = EmbeddedDocumentField(LightSaber)
+
+        coll = Jedi._get_collection()
+        Jedi(light_saber=LightSaber(color="red")).save()
+        _ = list(Jedi.objects)  # Ensure a proper document loads without errors
+
+        # Forces a document with a wrong shape (may occur in case of migration)
+        value = u"I_should_be_a_dict"
+        coll.insert_one({"light_saber": value})
+
+        with self.assertRaises(InvalidDocumentError) as cm:
+            list(Jedi.objects)
+
+        self.assertEqual(
+            str(cm.exception),
+            "Invalid data to create a `Jedi` instance.\nField 'light_saber' - The source SON object needs to be of type 'dict' but a '%s' was found"
+            % type(value),
+        )
+
 
 class ObjectKeyTestCase(MongoDBTestCase):
     def test_object_key_simple_document(self):