From 21f78b1ae0a12a97fc593dabe2c167a6acd88309 Mon Sep 17 00:00:00 2001 From: "Victor Piryns (pivi)" Date: Fri, 28 Oct 2022 14:59:59 +0000 Subject: [PATCH] [FIX] web, stock: rollback database when crashing on report generation Current behaviour: When we are printing a report and then the report fails to generate (for ex. wkhtmltopdf memory limit/timeout), the incorrect state is committed to the database. Expected behaviour: We should rollback when generating reports fails, since it is an error state. Steps to reproduce: To reproduce the behaviour, we need to force an error state. - In odoo/addons/base/models/ir_actions_report.py:`_run_wkhtmltopdf()`, raise an exception before spawning the subprocess (for ex. adding a 1/0). - In addons/web/controllers/main.py:`report_download()`#L2126, add this little code snippet: ```python ids = [int(x) for x in docids.split(",")] report = request.env['ir.actions.report']._get_report_from_name(reportname) obj = request.env[report.model].browse(ids) if getattr(obj, 'message_post'): obj.message_post(body='This report was committed!') ``` - Install Inventory - Pick a delivery order and try to print it, there should be an error (whatever exception you decided to raise in `_run_wkhtmltopdf()`) - See that in the message board we got a message that the report has been committed, which isn't the case, it failed to generate. Reason for the problem: Controllers are catching the exception when generating reports, but never reset the state of the database. Fix: Raise an InternalServerError with an error code of 500 to trigger a database rollback. Affected versions: - 14.0 - 15.0 - saas-15.2 - saas-15.3 - 16.0 - master opw-3001950 closes odoo/odoo#106172 X-original-commit: ec185fcf7f32da05c83733af36bebe10ac22e2ad Related: odoo/enterprise#34193 Signed-off-by: Julien Castiaux Signed-off-by: Piryns Victor (pivi) --- addons/stock/controllers/main.py | 10 ++++++++-- addons/web/controllers/report.py | 8 ++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/addons/stock/controllers/main.py b/addons/stock/controllers/main.py index f508ba19ffd..805b9378428 100644 --- a/addons/stock/controllers/main.py +++ b/addons/stock/controllers/main.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- +import werkzeug +from werkzeug.exceptions import InternalServerError from odoo import http from odoo.http import request -from odoo.tools import html_escape import json @@ -32,4 +33,9 @@ class StockReportController(http.Controller): 'message': 'Odoo Server Error', 'data': se } - return request.make_response(html_escape(json.dumps(error))) + res = werkzeug.wrappers.Response( + json.dumps(error), + status=500, + headers=[("Content-Type", "application/json")] + ) + raise InternalServerError(response=res) from e diff --git a/addons/web/controllers/report.py b/addons/web/controllers/report.py index 8ba955f378d..e7001a11c9d 100644 --- a/addons/web/controllers/report.py +++ b/addons/web/controllers/report.py @@ -12,7 +12,6 @@ from werkzeug.urls import url_parse from odoo import http from odoo.http import content_disposition, request -from odoo.tools import html_escape from odoo.tools.safe_eval import safe_eval, time @@ -144,7 +143,12 @@ class ReportController(http.Controller): 'message': "Odoo Server Error", 'data': se } - return request.make_response(html_escape(json.dumps(error))) + res = werkzeug.wrappers.Response( + json.dumps(error), + status=500, + headers=[("Content-Type", "application/json")] + ) + raise werkzeug.exceptions.InternalServerError(response=res) from e @http.route(['/report/check_wkhtmltopdf'], type='json', auth="user") def check_wkhtmltopdf(self):