[CORD-2548] Improving error reporting when setattr fails on an ORMWrapper class

Change-Id: I9116a67b5b30a793f887561aa5901d032f6f81a0
diff --git a/src/tosca/parser.py b/src/tosca/parser.py
index b30f716..854ff00 100644
--- a/src/tosca/parser.py
+++ b/src/tosca/parser.py
@@ -20,6 +20,7 @@
 from grpc_client.models_accessor import GRPCModelsAccessor
 from grpc._channel import _Rendezvous
 import json
+import traceback
 
 class TOSCA_Parser:
 
@@ -100,7 +101,10 @@
         for k,v in data.iteritems():
             # NOTE must-exists is a TOSCA implementation choice, remove it before saving the model
             if k != "must-exist":
-                setattr(model, k, v)
+                try:
+                    setattr(model, k, v)
+                except TypeError, e:
+                    raise Exception('Failed to set %s on field %s for class %s, Exception was: "%s"' % (v, k, model.model_name, e))
         return model
 
     @staticmethod
@@ -226,6 +230,7 @@
                     self.saved_model_by_name[recipe.name] = model
                 except Exception, e:
                     print "[XOS-TOSCA] Failed to save model: %s [%s]" % (class_name, recipe.name)
+                    traceback.print_exc()
                     raise e
 
         except ValidationError as e:
diff --git a/test/test_tosca_parser.py b/test/test_tosca_parser.py
index 829fed0..c8ad4bf 100644
--- a/test/test_tosca_parser.py
+++ b/test/test_tosca_parser.py
@@ -161,6 +161,34 @@
         self.assertEqual(model.foo, 'bar')
         self.assertEqual(model.number, 1)
 
+    def test_populate_model_error(self):
+        """
+        [TOSCA_Parser] populate_model: should print a meaningful error message
+        """
+
+        class FakeModel:
+
+            model_name = "FakeModel"
+
+            def __setattr__(self, name, value):
+                if name == 'foo':
+                    raise TypeError('reported exception')
+                else:
+                    super(FakeModel, self).__setattr__(name, value)
+
+        data = {
+            'name': 'test',
+            'foo': None,
+            'number': 1
+        }
+
+
+        model = FakeModel()
+
+        with self.assertRaises(Exception) as e:
+            model = TOSCA_Parser.populate_model(model, data)
+        self.assertEqual(e.exception.message, 'Failed to set None on field foo for class FakeModel, Exception was: "reported exception"')
+
     def test_translate_exception(self):
         """
         [TOSCA_Parser] translate_exception: convert a TOSCA Parser exception in a user readable string