[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 9 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
|
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.
|
Hello @grindtildeath Thanks for this PR. But I did a test and it is not working as expected. On a demo database with only sale-workflow.webmAs you can see in the video, after clicking on the confirm button of the sale order, I have the new exception and the client order ref field did not change, all good on this part. Can you check this issue please ? |
Simplify the JS layer by leveraging client actions. Return a custom client action whenever the BaseExceptionError is catched on RPC call and handle everything through the call to action_popup_exceptions: - In case exception should not pop up, return a soft reload client action instead of handling the refresh manually in JS - In case exception should pop up, return the wizard action, but do a soft reload first to display the exception_ids block before execution the wizard opening action.
|
@florian-dacosta Thanks for your feedback. I reworked the JS part to make it cleaner and simpler, it seems to solve your issue and works seamlessly on my side. Would be good if you can test again. |
ivantodorovich
left a comment
There was a problem hiding this comment.
CI fails due to pre-commit
florian-dacosta
left a comment
There was a problem hiding this comment.
@grindtildeath
It seems to work pretty well now, but there is still an issue.
I test with sale_exception, and if I run the cron to test the exceptions on draft order, manually (with button method_direct_trigger), I have this error
AttributeError: The method 'ir.cron.action_popup_exceptions' does not exist
This is because the button on ir.cron do trigger the BaseExceptionError.
… to reload smoothly
|
@florian-dacosta Tanks for the feedback, must be fixed now |
|
Thanks for the fix @grindtildeath It does not seem to be a big problem since the exceptions are commited anyway, but Also, I guess we may have situation with the inverse issue we try to fix here. I am not blocking anything as for now, the gain seems better than the potential loss, but I think it may be an issue. |
simahawk
left a comment
There was a problem hiding this comment.
LGTM. As for version bump I would go for major.
| def _must_raise_exception_after_detection(self): | ||
| return not all( | ||
| rec.ignore_exception for rec in self if rec.exception_ids | ||
| ) or any(rule.is_blocking for rule in self.mapped("exception_ids")) |
There was a problem hiding this comment.
| ) or any(rule.is_blocking for rule in self.mapped("exception_ids")) | |
| ) or any(rule.is_blocking for rule in self.exception_ids) |
| error.exceptionName === | ||
| "odoo.addons.base_exception.exceptions.BaseExceptionError" | ||
| ) { | ||
| if (error.data.message.split(":")[1].trim() === params.model) { |
There was a problem hiding this comment.
If I get it right when looking at If you register the exception into any of these registries, you won't need this patch:
const errorHandlerRegistry = registry.category("error_handlers");
const errorDialogRegistry = registry.category("error_dialogs");
const errorNotificationRegistry = registry.category("error_notifications");
The second one is probably the right one.
Not a blocker but maybe we can add a TODO here 😉
|
@florian-dacosta If I get your explanation right, it sounds like a side effect that is not fully in control. To allow devs to still store some information before the exception is raised we could add an hook and pass to it the new env. This way you can control it in a very explicit way. Not a blocker. maybe we can add a TODO in the roadmap. |
I was more thinking on a context to get rid of the raise. Well anyway, not a blocker like I said, maybe it is anticipating an issue we won't ever have. I have no usecase in mind, just thought about the possible side effects. |
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: