From f833e4e21b78979feecfd0f4f3ecb80f086c9804 Mon Sep 17 00:00:00 2001 From: Sagar Vora <16315650+sagarvora@users.noreply.github.com> Date: Wed, 18 Jun 2025 10:57:46 +0000 Subject: [PATCH] fix: improve flow to rollback db transaction when processing requests (#32980) * fix: improve flow to rollback db transaction when processing requests * fix: rollback, log request and process response for HTTPException --- frappe/app.py | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/frappe/app.py b/frappe/app.py index 69c0e76847..d8d259e066 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -92,8 +92,6 @@ def application(request: Request): response = None try: - rollback = True - init_request(request) validate_auth() @@ -127,23 +125,19 @@ def application(request: Request): else: raise NotFound - except HTTPException as e: - return e - except Exception as e: - response = handle_exception(e) + response = e.get_response(request.environ) if isinstance(e, HTTPException) else handle_exception(e) + if db := getattr(frappe.local, "db", None): + db.rollback() else: - rollback = sync_database(rollback) + sync_database() finally: # Important note: # this function *must* always return a response, hence any exception thrown outside of # try..catch block like this finally block needs to be handled appropriately. - if rollback and request.method in UNSAFE_HTTP_METHODS and frappe.db: - frappe.db.rollback() - try: run_after_request_hooks(request, response) except Exception: @@ -396,21 +390,21 @@ def handle_exception(e): return response -def sync_database(rollback: bool) -> bool: +def sync_database(): + db = getattr(frappe.local, "db", None) + if not db: + # db isn't initialized, can't commit or rollback + return + # if HTTP method would change server state, commit if necessary - if frappe.db and (frappe.local.flags.commit or frappe.local.request.method in UNSAFE_HTTP_METHODS): - frappe.db.commit() - rollback = False - elif frappe.db: - frappe.db.rollback() - rollback = False + if frappe.local.request.method in UNSAFE_HTTP_METHODS or frappe.local.flags.commit: + db.commit() + else: + db.rollback() # update session if session := getattr(frappe.local, "session_obj", None): - if session.update(): - rollback = False - - return rollback + session.update() # Always initialize sentry SDK if the DSN is sent