base_jsonify: fail gracefully
It could happen that a module adds an ir.export.line for a new field but when tests run the field is not loaded if this module is not a dependency of the module running tests. Furthermore, in general, it seems too strict to break the whole computation if there's a field that is missing. It seems more reasonable to log an error when this happen so that technical action can be taken to fix it.pull/2418/head
parent
90c2511706
commit
0ffc105bff
|
@ -5,12 +5,16 @@
|
|||
# Simone Orsi <simahawk@gmail.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
import logging
|
||||
|
||||
from odoo import api, fields, models, tools
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools.translate import _
|
||||
|
||||
from .utils import convert_simple_to_full_parser
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
|
||||
|
@ -70,17 +74,47 @@ class Base(models.AbstractModel):
|
|||
@api.model
|
||||
def _jsonify_record(self, parser, rec, root):
|
||||
"""Jsonify one record (rec). Private function called by jsonify."""
|
||||
strict = self.env.context.get("jsonify_record_strict", False)
|
||||
for field in parser:
|
||||
field_dict, subparser = rec.__parse_field(field)
|
||||
field_name = field_dict["name"]
|
||||
if field_name not in rec._fields:
|
||||
if strict:
|
||||
# let it fail
|
||||
rec._fields[field_name] # pylint: disable=pointless-statement
|
||||
if not tools.config["test_enable"]:
|
||||
# If running live, log proper error
|
||||
# so that techies can track it down
|
||||
_logger.error(
|
||||
"%(model)s.%(fname)s not available",
|
||||
{"model": self._name, "fname": field_name},
|
||||
)
|
||||
continue
|
||||
json_key = field_dict.get("target", field_name)
|
||||
field = rec._fields[field_name]
|
||||
if field_dict.get("function"):
|
||||
function = field_dict["function"]
|
||||
value = self._function_value(rec, function, field_name)
|
||||
try:
|
||||
value = self._function_value(rec, function, field_name)
|
||||
except UserError:
|
||||
if strict:
|
||||
raise
|
||||
if not tools.config["test_enable"]:
|
||||
_logger.error(
|
||||
"%(model)s.%(func)s not available",
|
||||
{"model": self._name, "func": str(function)},
|
||||
)
|
||||
continue
|
||||
elif subparser:
|
||||
if not (field.relational or field.type == "reference"):
|
||||
self._jsonify_bad_parser_error(field_name)
|
||||
if strict:
|
||||
self._jsonify_bad_parser_error(field_name)
|
||||
if not tools.config["test_enable"]:
|
||||
_logger.error(
|
||||
"%(model)s.%(fname)s not relational",
|
||||
{"model": self._name, "fname": field_name},
|
||||
)
|
||||
continue
|
||||
value = [
|
||||
self._jsonify_record(subparser, r, {}) for r in rec[field_name]
|
||||
]
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# Copyright 2017 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import fields
|
||||
import mock
|
||||
|
||||
from odoo import fields, tools
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests.common import SavepointCase
|
||||
|
||||
|
@ -310,15 +312,41 @@ class TestParser(SavepointCase):
|
|||
|
||||
self.assertDictEqual(json_menu, {"action": "Users"})
|
||||
|
||||
def test_bad_parsers(self):
|
||||
def test_bad_parsers_strict(self):
|
||||
rec = self.category.with_context(jsonify_record_strict=True)
|
||||
bad_field_name = ["Name"]
|
||||
with self.assertRaises(KeyError):
|
||||
self.category.jsonify(bad_field_name, one=True)
|
||||
rec.jsonify(bad_field_name, one=True)
|
||||
|
||||
bad_function_name = {"fields": [{"name": "name", "function": "notafunction"}]}
|
||||
with self.assertRaises(UserError):
|
||||
self.category.jsonify(bad_function_name, one=True)
|
||||
rec.jsonify(bad_function_name, one=True)
|
||||
|
||||
bad_subparser = {"fields": [({"name": "name"}, [{"name": "subparser_name"}])]}
|
||||
with self.assertRaises(UserError):
|
||||
self.category.jsonify(bad_subparser, one=True)
|
||||
rec.jsonify(bad_subparser, one=True)
|
||||
|
||||
def test_bad_parsers_fail_gracefully(self):
|
||||
rec = self.category
|
||||
|
||||
logger_patch_path = "odoo.addons.base_jsonify.models.models._logger.error"
|
||||
|
||||
# logging is disabled when testing as it's useless and makes build fail.
|
||||
tools.config["test_enable"] = False
|
||||
|
||||
bad_field_name = ["Name"]
|
||||
with mock.patch(logger_patch_path) as mocked_logger:
|
||||
rec.jsonify(bad_field_name, one=True)
|
||||
mocked_logger.assert_called()
|
||||
|
||||
bad_function_name = {"fields": [{"name": "name", "function": "notafunction"}]}
|
||||
with mock.patch(logger_patch_path) as mocked_logger:
|
||||
rec.jsonify(bad_function_name, one=True)
|
||||
mocked_logger.assert_called()
|
||||
|
||||
bad_subparser = {"fields": [({"name": "name"}, [{"name": "subparser_name"}])]}
|
||||
with mock.patch(logger_patch_path) as mocked_logger:
|
||||
rec.jsonify(bad_subparser, one=True)
|
||||
mocked_logger.assert_called()
|
||||
|
||||
tools.config["test_enable"] = True
|
||||
|
|
Loading…
Reference in New Issue