diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py index 5a8fa3973ac8732d9e00d11e151adf8ffec394ae..4d2510cabd37bc1f823b261fa1286ab2b3951c50 100644 --- a/src/caosdb/common/models.py +++ b/src/caosdb/common/models.py @@ -3961,17 +3961,18 @@ def _evaluate_and_add_error(parent_error, ent): dummy_err = EntityError(entity=ent) for prop in ent.get_properties(): dummy_err = _evaluate_and_add_error(dummy_err, prop) - if dummy_err.get_errors(): + if dummy_err.errors: parent_error.add_error(dummy_err) if not found116: dummy_err = EntityError(entity=ent) for par in ent.get_parents(): dummy_err = _evaluate_and_add_error(dummy_err, par) - if dummy_err.get_errors(): + if dummy_err.errors: parent_error.add_error(dummy_err) elif isinstance(ent, Container): parent_error.container = ent + parent_error.code = ent.get_errors()[0].code if ent.get_errors() is not None: # In the highly unusual case of more than one error # message, attach all of them. @@ -4007,8 +4008,8 @@ def raise_errors(arg0): raise transaction_error # Cover the special case of an empty container with error # message(s) (e.g. query syntax error) - if (transaction_error.get_container() is not None and - transaction_error.get_container().has_errors()): + if (transaction_error.container is not None and + transaction_error.container.has_errors()): raise transaction_error diff --git a/src/caosdb/exceptions.py b/src/caosdb/exceptions.py index 61f016e36a633837b4e98aaf9b49368b4efb7bd8..c54a894f184741d2f6555400d0509f4cd145e73e 100644 --- a/src/caosdb/exceptions.py +++ b/src/caosdb/exceptions.py @@ -162,6 +162,11 @@ class TransactionError(CaosDBException): self.entities = [] self.all_entities = set() self.container = container + # special case of faulty container + if container is not None and container.get_errors() is not None: + self.code = container.get_errors()[0].code + else: + self.code = None if error is not None: self.add_error(error) @@ -262,6 +267,10 @@ class EntityError(TransactionError): def __init__(self, error=None, entity=None): TransactionError.__init__(self) self.error = error + if hasattr(error, "code"): + self.code = error.code + else: + self.code = None self.entity = entity if error is not None and hasattr(error, "encode"): diff --git a/unittests/test_error_handling.py b/unittests/test_error_handling.py index d677bba5c6cab53703dc0f492d2289d63ca5b6ba..998766c7773c023bf240b249ad658940958302cd 100644 --- a/unittests/test_error_handling.py +++ b/unittests/test_error_handling.py @@ -128,8 +128,8 @@ def test_empty_container_with_error(): raise_errors(cont) # No entity errors assert len(e.value.errors) == 0 - assert e.value.get_container() == cont - assert int(e.value.get_code()) == code + assert e.value.container == cont + assert int(e.value.code) == code def test_faulty_container_with_healthy_entities(): @@ -146,8 +146,8 @@ def test_faulty_container_with_healthy_entities(): # No entity errors assert len(e.value.errors) == 0 assert len(e.value.entities) == 0 - assert e.value.get_container() == cont - assert int(e.value.get_code()) == code + assert e.value.container == cont + assert int(e.value.code) == code # #################### Children with children #################### @@ -202,7 +202,7 @@ def test_unqualified_properties_error(): for error_t in [UnqualifiedPropertiesError, EntityError, EntityDoesNotExistError]: assert any([isinstance(x, error_t) for x in te.all_errors]) - assert upe.get_code() == code + assert upe.code == code # #################### Multiple errors #################### @@ -239,21 +239,21 @@ def test_parent_and_properties_errors(): found_parent = False found_prop = False for err in te.errors: - if err.get_code() == parent_code: + if err.code == parent_code: found_parent = True assert err.errors[0].entity.name == parent.name assert prop1.name not in [x.name for x in err.all_entities] assert prop2.name not in [x.name for x in err.all_entities] - elif err.get_code() == prop_code: + elif err.code == prop_code: found_prop = True assert parent.name not in [x.name for x in err.all_entities] for sub_err in err.errors: - if sub_err.get_code() == entity_code: + if sub_err.code == entity_code: assert sub_err.entity.name == prop1.name - elif sub_err.get_code() == no_entity_code: + elif sub_err.code == no_entity_code: assert sub_err.entity.name == prop2.name assert found_parent assert found_prop @@ -299,8 +299,8 @@ def test_container_with_faulty_elements(): with raises(TransactionError) as e: raise_errors(cont) te = e.value - assert te.get_container() == cont - assert te.get_code() == container_code + assert te.container == cont + assert te.code == container_code # no healthy entity caused an error for good in [good_rec, good_prop]: assert good not in te.all_entities @@ -316,56 +316,3 @@ def test_container_with_faulty_elements(): # record raises both of them assert (isinstance(err, UnqualifiedParentsError) or isinstance(err, UnqualifiedPropertiesError)) - - -def test_convenience_functions(): - """Test whether get_error and and get_entity work and break as - intended, and whether has_error works properly. - - """ - # Only one child - no_entity_code = 101 - ent = _add_error_message_to_entity( - db.Entity(name="TestEnt"), no_entity_code) - with raises(TransactionError) as e: - raise_errors(ent) - te = e.value - # Works since there is exactly one child - assert te.get_entity().name == ent.name - assert te.get_error() == ent.get_errors()[0] - # Has to have this - assert te.has_error(EntityDoesNotExistError) - # EntityDoesNotExistError is an EntityError - assert te.has_error(EntityError) - # Shouldn't be there - assert not te.has_error(UniqueNamesError) - - # Two children - prop_code = 114 - parent_code = 116 - entity_code = 0 - parent = _add_error_message_to_entity( - db.RecordType(name="TestParent"), no_entity_code) - prop1 = _add_error_message_to_entity(db.Property( - name="TestProp1"), entity_code) - prop2 = _add_error_message_to_entity(db.Property( - name="TestProp2"), no_entity_code) - rec = _add_error_message_to_entity(db.Record(name="TestRecord"), - prop_code) - rec = _add_error_message_to_entity(rec, parent_code) - rec.add_parent(parent) - rec.add_property(prop1).add_property(prop2) - with raises(TransactionError) as e: - raise_errors(rec) - te = e.value - # Two children, should raise an Error - with raises(AmbiguityException): - te.get_error() - with raises(AmbiguityException): - te.get_entity() - for error_t in [EntityDoesNotExistError, UnqualifiedParentsError, - UnqualifiedPropertiesError]: - assert te.has_error(error_t) - # Not, if limitted to direct children - assert not te.has_error(EntityDoesNotExistError, - direct_children_only=True)