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
This commit is contained in:
Sagar Vora 2025-06-18 10:57:46 +00:00 committed by GitHub
parent 8fbe452b4d
commit f833e4e21b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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