From f0d4240082fd2dd9ad109bfd7e3caead27410aa3 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 17 Mar 2014 17:32:28 +0100 Subject: [PATCH] [FIX] http dispatch: make sure transaction rollback happens in all cases when request handling raised (to be refactored) Not doing so leads to cases where a transaction is committed even after failing to validate a Python constraint. This patch attempts to keep the rollback() logic next to the corresponding commit(), and makes the rollback() more explicit even if close() without commit() would also rollback implicitly. bzr revid: odo@openerp.com-20140317163228-zqbce8f0rgcg0pt4 --- openerp/http.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openerp/http.py b/openerp/http.py index 5b01922bfb5..61c90929aa2 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -135,6 +135,10 @@ class WebRequest(object): self._cr_cm = None self._cr = None self.func_request_type = None + + # prevents transaction commit, use when you catch an exception during handling + self._failed = None + # set db/uid trackers - they're cleaned up at the WSGI # dispatching phase in openerp.service.wsgi_server.application if self.db: @@ -178,8 +182,11 @@ class WebRequest(object): def __exit__(self, exc_type, exc_value, traceback): _request_stack.pop() if self._cr: - if exc_type is None: + if exc_type is None and not self._failed: self._cr.commit() + else: + # just to be explicit - happens at close() anyway + self._cr.rollback() self._cr.close() # just to be sure no one tries to re-use the request self.disable_db = True @@ -350,6 +357,7 @@ class JsonRequest(WebRequest): 'message': "OpenERP Session Invalid", 'data': se } + self._failed = e # prevent tx commit except Exception, e: _logger.exception("Exception during JSON request handling.") se = serialize_exception(e) @@ -358,6 +366,7 @@ class JsonRequest(WebRequest): 'message': "OpenERP Server Error", 'data': se } + self._failed = e # prevent tx commit if error: response["error"] = error