odoo / odoo

Odoo. Open Source Apps To Grow Your Business.
https://www.odoo.com
Other
37.29k stars 24.25k forks source link

Improve Quality of Error messages #138044

Open mohs8421 opened 11 months ago

mohs8421 commented 11 months ago

When writing code for Odoo, errors happen, but handling errors should be in a way that supports users to overcome these errors.

Impacted versions: 16.0.0

Steps to reproduce:

  1. Create a module and integrate an xml file, that contains an error like this:
        <record id="foo" model="ir.rule">
            <field name="name">Foo</field>
            <field name="model_id" ref="model_product_template"/>
            <field name="groups" ref="this is wrong"/>
            <field name="domain_force">[('foo','=',False)]</field>
        </record>

Current behavior: Odoo does not indicate what was wrong in a xml file, but just errors with an exception Example:

ERROR odoo odoo.http: Exception during request handling. 
Traceback (most recent call last):
  File "modules/registry.py", line 64, in __new__
    return cls.registries[db_name]
  File "<decorator-gen-6>", line 2, in __getitem__
  File "tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
  File "tools/lru.py", line 34, in __getitem__
    a = self.d[obj]
KeyError: 'odoo'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tools/convert.py", line 698, in _tag_root
    f(rec)
  File "tools/convert.py", line 599, in _tag_record
    record = model._load_records([data], self.mode == 'update')
  File "models.py", line 4397, in _load_records
    records = self._load_records_create([data['values'] for data in to_create])
  File "models.py", line 4308, in _load_records_create
    return self.create(values)
  File "<decorator-gen-62>", line 2, in create
  File "api.py", line 410, in _model_create_multi
    return create(self, arg)
  File "addons/base/models/ir_rule.py", line 174, in create
    res = super(IrRule, self).create(vals_list)
  File "<decorator-gen-65>", line 2, in create
  File "api.py", line 410, in _model_create_multi
    return create(self, arg)
  File "addons/base/models/ir_fields.py", line 670, in create
    recs = super().create(vals_list)
  File "<decorator-gen-13>", line 2, in create
  File "api.py", line 410, in _model_create_multi
    return create(self, arg)
  File "models.py", line 3964, in create
    records = self._create(data_list)
  File "models.py", line 4201, in _create
    field.create([
  File "fields.py", line 4248, in create
    self.write_batch(record_values, True)
  File "fields.py", line 4269, in write_batch
    raise ValueError("Wrong value for %s: %s" % (self, value))
ValueError: Wrong value for ir.rule.groups: 184

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "http.py", line 1998, in __call__
    response = request._serve_db()
  File "http.py", line 1563, in _serve_db
    self.registry = Registry(self.db).check_signaling()
  File "modules/registry.py", line 66, in __new__
    return cls.new(db_name)
  File "<decorator-gen-14>", line 2, in new
  File "tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
  File "modules/registry.py", line 90, in new
    odoo.modules.load_modules(registry, force_demo, status, update_module)
  File "modules/loading.py", line 484, in load_modules
    processed_modules += load_marked_modules(cr, graph,
  File "modules/loading.py", line 372, in load_marked_modules
    loaded, processed = load_module_graph(
  File "modules/loading.py", line 231, in load_module_graph
    load_data(cr, idref, mode, kind='data', package=package)
  File "modules/loading.py", line 71, in load_data
    tools.convert_file(cr, package.name, filename, idref, mode, noupdate, kind)
  File "tools/convert.py", line 763, in convert_file
    convert_xml_import(cr, module, fp, idref, mode, noupdate)
  File "tools/convert.py", line 829, in convert_xml_import
    obj.parse(doc.getroot())
  File "tools/convert.py", line 749, in parse
    self._tag_root(de)
  File "tools/convert.py", line 698, in _tag_root
    f(rec)
  File "tools/convert.py", line 711, in _tag_root
    raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing foo_module/security/foo.xml:10, somewhere inside
<record id="foo" model="ir.rule">
            <field name="name">Foo</field>
            <field name="model_id" ref="model_product_template"/>
            <field name="groups" ref="this is wrong"/>
            <field name="domain_force">[('foo','=',False)]</field>
        </record>

What this error message is trying to tell me is that the reference I used was not found, I assume this is a very common case on a system where many items refer to each other by names.

Expected behavior: Instead of laying out the internals of odoo, it would be better to point out what was wrong in the xml file. Compare this wall of text to a compile error in rust, one of these is mocking you, the other one teaches you and encourages you to improve.

Addition: I should be more specific about how it should behave here. There are 4 Questions every error message should try to answer:

  1. What is the issue?
  2. Where did it happen?
  3. Why is it a problem?
  4. How can I resolve this?

I can see, how especially question 2 might lead to the answer "Well there is a stack trace, it shows where that thing happened", but that might be very misleading, especially when it's about parsing an xml file. In that case the internals of the parsing mechanism do not help understanding what was wrong in the xml file.

Additionally there should be some boundaries. For example between modules and the odoo framework. If there is an error happening in a module it should not leak into the framework, and the framework should always give a reasonable answer to clients. Responses with blank pages should be a thing of the past.

mohs8421 commented 2 months ago

An other example of a completely not helpful message:

2024-06-25[…] 4 WARNING [REDACTED] py.warnings: /home/odoo/src/odoo/odoo/addons/base/models/ir_module.py:178: DeprecationWarning: XML declarations in HTML module descriptions are deprecated since Odoo 17, report_xlsx can just have a UTF8 description with not need for a declaration.
  File "/home/odoo/src/odoo/odoo-bin", line 8, in <module>
    odoo.cli.main()
  File "/home/odoo/src/odoo/odoo/cli/command.py", line 66, in main
    o.run(args)
  File "/home/odoo/src/odoo/odoo/cli/server.py", line 179, in run
    main(args)
  File "/home/odoo/src/odoo/odoo/cli/server.py", line 172, in main
    rc = odoo.service.server.start(preload=preload, stop=stop)
  File "/home/odoo/src/odoo/odoo/service/server.py", line 1413, in start
    rc = server.run(preload, stop)
  File "/home/odoo/src/odoo/odoo/service/server.py", line 590, in run
    rc = preload_registries(preload)
  File "/home/odoo/src/odoo/odoo/service/server.py", line 1313, in preload_registries
    registry = Registry.new(dbname, update_module=update_module)
  File "<decorator-gen-16>", line 2, in new
  File "/home/odoo/src/odoo/odoo/tools/func.py", line 87, in locked
    return func(inst, *args, **kwargs)
  File "/home/odoo/src/odoo/odoo/modules/registry.py", line 113, in new
    odoo.modules.load_modules(registry, force_demo, status, update_module)
  File "/home/odoo/src/odoo/odoo/modules/loading.py", line 476, in load_modules
    processed_modules += load_marked_modules(env, graph,
  File "/home/odoo/src/odoo/odoo/modules/loading.py", line 364, in load_marked_modules
    loaded, processed = load_module_graph(
  File "/home/odoo/src/odoo/odoo/modules/loading.py", line 222, in load_module_graph
    module._check()
 File "/home/odoo/src/odoo/odoo/addons/base/models/ir_module.py", line 847, in _check
    if not module.description_html:
  File "/home/odoo/src/odoo/odoo/fields.py", line 1207, in __get__
    self.compute_value(recs)
  File "/home/odoo/src/odoo/odoo/fields.py", line 1389, in compute_value
    records._compute_field_value(self)
  File "/home/odoo/src/odoo/odoo/models.py", line 4875, in _compute_field_value
    fields.determine(field.compute, self)
  File "/home/odoo/src/odoo/odoo/fields.py", line 102, in determine
    return needle(*args)
  File "/home/odoo/src/odoo/odoo/addons/base/models/ir_module.py", line 178, in _get_desc
    warnings.warn(

There is exactly zero information in all this about the code that is actually in question. One can be glad, that there is a module name mentioned.