summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2019-05-27 06:58:48 +0000
committerXavier Morel <xmo@odoo.com>2019-05-27 06:58:48 +0000
commit16cd987a53bcc7c29af28b58bec8d8bf6cc1b9d7 (patch)
tree14d22691be9801986bb133adac3d614399e8d15f
parent9b823c9c6a6333ee9b13cd2096afe46cbf8eddd5 (diff)
[IMP] validation error messages through optional use of jing
A long-standing issue with data files is that lxml (libxml2) has trouble reporting useful errors, often going no further than "the file is not valid" (libxml2 apparently has issues reporting useful errors within non-trivial <choice>, which Odoo's data file schema makes extensive use of) e.g. if a data file has some stray text in an unexpected place (in this case, after a `</field>` tag in a `<record>`), libxml2 will report: ERROR:RELAXNGV:RELAXNG_ERR_EXTRACONTENT: Element odoo has extra content: data Jing (the reference implementation) provides significantly better error reporting: error: text not allowed here; expected the element end-tag or element "field" It's in java which is inconvenient and expensive for baseline validation (and as a hard dependency), but there's now a "jingtrang" package which bundles the relevant jars & invocation on pypi (https://pypi.org/project/jingtrang/), making for a convenient optional dependency for better development experience. closes odoo/odoo#33666 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
-rw-r--r--odoo/tools/convert.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index 599fb3a6e47..b2ea452192b 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -5,6 +5,7 @@ import io
import logging
import os.path
import re
+import subprocess
import sys
import time
@@ -13,6 +14,10 @@ from dateutil.relativedelta import relativedelta
import pytz
from lxml import etree, builder
+try:
+ import jingtrang
+except ImportError:
+ jingtrang = None
import odoo
from . import assertion_report, pycompat
@@ -771,13 +776,19 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=False, report=None):
doc = etree.parse(xmlfile)
- relaxng = etree.RelaxNG(
- etree.parse(os.path.join(config['root_path'],'import_xml.rng' )))
+ schema = os.path.join(config['root_path'], 'import_xml.rng')
+ relaxng = etree.RelaxNG(etree.parse(schema))
try:
relaxng.assert_(doc)
except Exception:
- _logger.info("The XML file '%s' does not fit the required schema !", xmlfile.name, exc_info=True)
- _logger.info(ustr(relaxng.error_log.last_error))
+ _logger.exception("The XML file '%s' does not fit the required schema !", xmlfile.name)
+ if jingtrang:
+ p = subprocess.run(['pyjing', schema, xmlfile.name], stdout=subprocess.PIPE)
+ _logger.warn(p.stdout.decode())
+ else:
+ for e in relaxng.error_log:
+ _logger.warn(e)
+ _logger.info("Install 'jingtrang' for more precise and useful validation messages.")
raise
if isinstance(xmlfile, str):