From 111af8e7205b04464aa35a0ae5ff2bf740bee339 Mon Sep 17 00:00:00 2001
From: "Victor Piryns (pivi)" <pivi@odoo.com>
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#106027

X-original-commit: d7fdcdce36909adf43e48130e6079a1d41f20238
Related: odoo/enterprise#34113
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Piryns Victor (pivi) <pivi@odoo.com>
---
 addons/stock/controllers/main.py | 10 ++++++++--
 addons/web/controllers/main.py   |  7 ++++++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/addons/stock/controllers/main.py b/addons/stock/controllers/main.py
index 4856967ab44d..4ef2a51fd8f3 100644
--- a/addons/stock/controllers/main.py
+++ b/addons/stock/controllers/main.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
+import werkzeug
+from werkzeug.exceptions import InternalServerError
 
 from odoo import http
 from odoo.http import request
 from odoo.addons.web.controllers.main import _serialize_exception
-from odoo.tools import html_escape
 
 import json
 
@@ -33,4 +34,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/main.py b/addons/web/controllers/main.py
index 669562dd2217..59033ab4f397 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -2045,7 +2045,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):
-- 
GitLab