[18.0][FIX] base_exception: Rollback transaction if we detect exceptions#3590
[18.0][FIX] base_exception: Rollback transaction if we detect exceptions#3590grindtildeath wants to merge 3 commits intoOCA:18.0from
Conversation
|
Hi @sebastienbeau, @hparfr, |
| raise_exception = False | ||
| # Write exceptions in a new transaction to be committed so that we can | ||
| # rollback the ongoing one while keeping the exceptions stored | ||
| with Registry(self.env.cr.dbname).cursor() as new_cr: |
There was a problem hiding this comment.
| with Registry(self.env.cr.dbname).cursor() as new_cr: | |
| with self.env.registry.cursor() as new_cr: |
no need to initialize a new registry
| # Write exceptions in a new transaction to be committed so that we can | ||
| # rollback the ongoing one while keeping the exceptions stored | ||
| with Registry(self.env.cr.dbname).cursor() as new_cr: | ||
| new_env = Environment(new_cr, self.env.uid, self.env.context) |
There was a problem hiding this comment.
| new_env = Environment(new_cr, self.env.uid, self.env.context) | |
| records_env = records.with_env(self.env(cr=new_cr)) |
to avoid all the with_env everytime you read/write, initialize a records_env variable.
also you can use self.env(cr=) like this
There was a problem hiding this comment.
Actually we have many sets of records:
- self
- values of rules_to_add
- values of rules_to_add
For each one we need to use the new cursor, so I guess it makes sense to create the new_env this way. AFAIU self.env(cr=new_cr) would just do the same, but we need to reuse it many times anyway
| # 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 | ||
| if ( | ||
| rules_to_add | ||
| or not all( | ||
| rec.ignore_exception | ||
| for rec in self.with_env(new_env) | ||
| if rec.exception_ids | ||
| ) | ||
| or any( | ||
| rule.is_blocking | ||
| for rule in self.with_env(new_env).mapped("exception_ids") | ||
| ) | ||
| ): | ||
| raise_exception = True |
There was a problem hiding this comment.
Maybe extract this to a method records_env._should_raise_exception ?
|
ping @florian-dacosta |
9e62007 to
4ea380d
Compare
This aims to solve issues when modules not depending on whatever implementation of base_exception, override the same function that triggers the detection of exceptions. Before this commit, any changes done in such overrides could end up being committed to the database if the MRO did execute such function before the function implementing base_exception that avoids to call super in case an exception is detected. (eg sale.order. action_confirm in sale_exception) With this commit, in case there is any newly detected exception, or a record with exception that is not ignored, or a blocking exception linked to a record, exception changes will be committed in DB while a specific Exception type will be raised to rollback any changes done in the ongoing transaction. Such an exception will be handled in the UI to refresh the exception_ids field so that the user knows why the action was not completed.
4ea380d to
61eed8a
Compare
With the previous change raising an exception to rollback a transaction, the function `_popup_exceptions` could not be called anymore while the error was raised. Instead, we provide now a hook `_must_popup_exception` that can be redefined by model and will be called when `action_popup_exception` is called by the webclient, to smoothly refresh the page and display the popup exception wizard.
With OCA/server-tools#3590 changing the way exceptions are detected, the error raising doesn't allow to call _popup_exception as we used to, but we can use the new hook to have the popup displayed as it used to.
With OCA/server-tools#3590 changing the way exceptions are detected, the error raising doesn't allow to call _popup_exception as we used to, but we can use the new hook to have the popup displayed as it used to.
With OCA/server-tools#3590 changing the way exceptions are detected, the error raising doesn't allow to call `_popup_exception` as we used to, but we can use the new hook to have the popup displayed smoothly.
With OCA/server-tools#3590 changing the way exceptions are detected, the error raising doesn't allow to call _popup_exception as we used to, but we can use the new hook to have the popup displayed smoothly.
…ollback With OCA/server-tools#3590 changing the way exceptions are detected, the error raising doesn't allow to call _popup_exception as we used to, but we can use the new hook to have the popup displayed smoothly.
|
ping @jok-adhoc @lav-adhoc @lef-adhoc @maq-adhoc @rousseldenis @florian-dacosta After spending hours on this issue, IMO this solves the core issue we have with non dependent module having their changes done in I then changed the way the exception popup can be displayed and it seems to work smoothly with no side effects and no need of glue modules. Could you guys please have a look, eventually test this (with their dependent PRs) and let me know what do you think? 🙏 |
rousseldenis
left a comment
There was a problem hiding this comment.
LGTM.
Great! @grindtildeath Thanks for this, this seems indeed cleaner to solve the historical issue we have with this.
This aims to solve issues when modules not depending on whatever implementation of base_exception, override the same function that triggers the detection of exceptions.
Before this commit, any changes done in such overrides could end up being committed to the database if the MRO did execute such function before the function implementing base_exception that avoids to call super in case an exception is detected. (eg sale.order. action_confirm in sale_exception)
With this commit, in case there is any newly detected exception, or a record with exception that is not ignored, or a blocking exception linked to a record, exception changes will be committed in DB while a specific Exception type will be raised to rollback any changes done in the ongoing transaction. Such an exception will be handled in the UI to refresh the exception_ids field so that the user knows why the action was not completed.
Replaces and fixes:
Dependent PRs: