diff --git a/README.md b/README.md
index 0d259c0b0ae..186a69b451e 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ addon | version | maintainers | summary
[autovacuum_message_attachment](autovacuum_message_attachment/) | 18.0.1.0.1 |
| Automatically delete old mail messages and attachments
[base_conditional_image](base_conditional_image/) | 18.0.1.0.0 | | This module extends the functionality to support conditional images
[base_cron_exclusion](base_cron_exclusion/) | 18.0.1.0.1 |
| Allow you to select scheduled actions that should not run simultaneously.
-[base_exception](base_exception/) | 18.0.1.1.2 |
| This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...)
+[base_exception](base_exception/) | 18.0.1.3.0 |
| This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...)
[base_fontawesome](base_fontawesome/) | 18.0.2.0.0 | | Up to date Fontawesome resources.
[base_fontawesome_web_editor](base_fontawesome_web_editor/) | 18.0.1.0.0 | | Integration between base_fontawesome and web_editor for FontAwesome >= 6.7.2 support.
[base_force_record_noupdate](base_force_record_noupdate/) | 18.0.1.0.0 | | Manually force noupdate=True on models
diff --git a/base_exception/README.rst b/base_exception/README.rst
index 0987d5141ee..46de37e496a 100644
--- a/base_exception/README.rst
+++ b/base_exception/README.rst
@@ -11,7 +11,7 @@ Exception Rule
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:bf43c9d6f42f7195b276ef11de74a1a145886fbc5928d55fe35e8763fb5fd866
+ !! source digest: sha256:97057fe274486f1fe87790f8eb4aa862ccd79dcd71321bd0d5c621ab90545b75
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
diff --git a/base_exception/__manifest__.py b/base_exception/__manifest__.py
index 54cb35736e0..e87075db29f 100644
--- a/base_exception/__manifest__.py
+++ b/base_exception/__manifest__.py
@@ -5,7 +5,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Exception Rule",
- "version": "18.0.1.1.2",
+ "version": "18.0.1.3.0",
"development_status": "Mature",
"category": "Generic Modules",
"summary": """
diff --git a/base_exception/models/base_exception_method.py b/base_exception/models/base_exception_method.py
index 9a34abf43be..7b934d634a8 100644
--- a/base_exception/models/base_exception_method.py
+++ b/base_exception/models/base_exception_method.py
@@ -90,9 +90,20 @@ def detect_exceptions(self):
# table
# and the "to add" part generates one INSERT (with unnest) per rule.
raise_exception = False
- test_mode = config["test_enable"] and not self.env.context.get(
- "test_base_exception"
- )
+ # The registry is not ready yet when modules are being installed or
+ # updated: the ongoing transaction holds exclusive locks on the tables
+ # it has just modified (ALTER TABLE ...), so any query made through a
+ # second connection would wait forever on those locks (and the locks
+ # cannot be released, as the current thread is the one waiting).
+ # Use the current cursor in that case, as already done when running
+ # tests.
+ test_mode = (
+ config["test_enable"] or not self.env.registry.ready
+ ) and not self.env.context.get("test_base_exception")
+ # Resolve the main records (e.g. the sale order behind a sale order
+ # line) using the current cursor, which sees records created earlier
+ # in this same transaction even before they are committed.
+ main_records = self._get_main_records()
# Write exceptions in a new transaction to be committed so that we can
# rollback the ongoing one while keeping the exceptions stored
with self.env.registry.cursor() as new_cr:
@@ -111,9 +122,21 @@ def detect_exceptions(self):
)
# In case we have new exception, or exceptions that were not ignored yet, or
# blocking exceptions, we need to raise an exception to rollback the
- # ongoing transaction
- self_new_env = self.with_env(new_env)
- if rules_to_add or self_new_env._must_raise_exception_after_detection():
+ # ongoing transaction.
+ # Re-derive main_records through new_env rather than re-running
+ # self.with_env(new_env)._get_main_records(): when self are
+ # records just created earlier in the ongoing (not yet committed)
+ # transaction (e.g. a line added while editing a confirmed sale
+ # order), new_cr is a genuinely separate DB connection that
+ # cannot see them yet, and _get_main_records() traversal
+ # (e.g. sale.order.line -> order_id) would raise MissingError.
+ # main_records itself was already resolved above through the
+ # current cursor, so only rebinding it to new_env is needed here.
+ main_records_new_env = main_records.with_env(new_env)
+ if (
+ rules_to_add
+ or main_records_new_env._must_raise_exception_after_detection()
+ ):
raise_exception = True
if raise_exception:
raise BaseExceptionError(
diff --git a/base_exception/static/description/index.html b/base_exception/static/description/index.html
index 54c84e8ede8..be728c51fcc 100644
--- a/base_exception/static/description/index.html
+++ b/base_exception/static/description/index.html
@@ -372,7 +372,7 @@
This module provide an abstract model to manage customizable exceptions