From 0e25a77a629b6196e5092641ee348bc47b361520 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Sun, 21 Jun 2026 15:48:32 +0530 Subject: [PATCH] fix(postgres): savepoint Plaid bank-account creation loop add_bank_accounts() inserts a Bank Account per Plaid account in a loop. On a duplicate the bare insert raises UniqueValidationError, which on Postgres aborts the whole transaction; the handler only msgprint'd and continued, so the next iteration's insert died with InFailedSqlTransaction. Wrap each iteration in a savepoint and roll back to it in the handlers (the pattern frappe#40075 prescribes after dropping the blanket per-insert savepoint). No-op on MariaDB. --- .../doctype/plaid_settings/plaid_settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py index 51bc540937f..36c2f8c7fc8 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py @@ -113,6 +113,8 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str): if not existing_bank_account: try: + # savepoint so a failed insert doesn't poison the transaction on postgres + frappe.db.savepoint("plaid_bank_account") gl_account = frappe.get_doc( { "doctype": "Account", @@ -142,12 +144,14 @@ def add_bank_accounts(response: str | dict, bank: str | dict, company: str): result.append(new_account.name) except frappe.UniqueValidationError: + frappe.db.rollback(save_point="plaid_bank_account") # preserve transaction in postgres frappe.msgprint( _("Bank account {0} already exists and could not be created again").format( account["name"] ) ) except Exception: + frappe.db.rollback(save_point="plaid_bank_account") # preserve transaction in postgres frappe.log_error("Plaid Link Error") frappe.throw( _("There was an error creating Bank Account while linking with Plaid."),