[FIX] core: better error message on wrong related path definitions

Before this commit, if a related field's path definition contained a
non-existing field (either because of a typo or field removal) the ORM
would simply send a generic Python KeyError that didn't really help in
debugging.

With this commit, we raise our own KeyError stating which related field
has the wrong path definition and exactly which field within the path is
incorrect.

See test for an example.

closes odoo/odoo#31889

Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
This commit is contained in:
Florent de Labarre
2021-07-16 10:17:30 +00:00
committed by Adrian Torres
parent eb70a581b9
commit 9e1e0ebb02
2 changed files with 25 additions and 1 deletions
@@ -3360,3 +3360,23 @@ class TestUnlinkConstraints(common.TransactionCase):
# should fail since it's at_uninstall=True
with self.assertRaises(ValueError, msg="You didn't say if you wanted it crudo or cotto..."):
self.undeletable_foo_uninstall.unlink()
@common.tagged('wrong_related_path')
class TestWrongRelatedError(common.TransactionCase):
def test_wrong_related_path(self):
class Foo(models.Model):
_module = None
_name = _description = 'test_new_api.wrong_related_path'
foo_id = fields.Many2one('test_new_api.foo')
foo_non_existing = fields.Char(related='foo_id.non_existing_field')
Foo._build_model(self.registry, self.env.cr)
self.addCleanup(self.registry.__delitem__, Foo._name)
errMsg = (
"Field non_existing_field referenced in related field definition "
"test_new_api.wrong_related_path.foo_non_existing does not exist."
)
with self.assertRaisesRegex(KeyError, errMsg):
self.registry.setup_models(self.env.cr)
+5 -1
View File
@@ -524,7 +524,11 @@ class Field(MetaField('DummyField', (object,), {})):
# determine the chain of fields, and make sure they are all set up
model_name = self.model_name
for name in self.related.split('.'):
field = model.pool[model_name]._fields[name]
field = model.pool[model_name]._fields.get(name)
if field is None:
raise KeyError(
f"Field {name} referenced in related field definition {self} does not exist."
)
if not field._setup_done:
field.setup(model.env[model_name])
model_name = field.comodel_name