diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 94e7bfc16d2..1ff33c7f7bf 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -363,5 +363,6 @@ erpnext.patches.v13_0.set_return_against_in_pos_invoice_references erpnext.patches.v13_0.copy_custom_field_filters_to_website_item erpnext.patches.v13_0.set_available_for_use_date_if_missing erpnext.patches.v13_0.education_deprecation_warning +erpnext.patches.v13_0.requeue_recoverable_reposts erpnext.patches.v13_0.create_accounting_dimensions_in_orders erpnext.patches.v13_0.set_per_billed_in_return_delivery_note diff --git a/erpnext/patches/v13_0/requeue_recoverable_reposts.py b/erpnext/patches/v13_0/requeue_recoverable_reposts.py new file mode 100644 index 00000000000..f37c21c9769 --- /dev/null +++ b/erpnext/patches/v13_0/requeue_recoverable_reposts.py @@ -0,0 +1,21 @@ +import frappe + + +def execute(): + recoverable = ("QueryDeadlockError", "QueryTimeoutError", "JobTimeoutException") + + failed_reposts = frappe.get_all( + "Repost Item Valuation", + fields=["name", "error_log"], + filters={ + "status": "Failed", + "docstatus": 1, + "modified": (">", "2022-04-20"), + "error_log": ("is", "set"), + }, + ) + for riv in failed_reposts: + for exc in recoverable: + if exc in riv.error_log: + frappe.db.set_value("Repost Item Valuation", riv.name, "status", "Queued") + break diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index b788fd1286b..b068d5fe3c3 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -3,9 +3,11 @@ import frappe from frappe import _ +from frappe.exceptions import QueryDeadlockError, QueryTimeoutError from frappe.model.document import Document from frappe.utils import cint, get_link_to_form, get_weekday, now, nowtime from frappe.utils.user import get_users_with_role +from rq.timeouts import JobTimeoutException import erpnext from erpnext.accounts.utils import get_future_stock_vouchers, repost_gle_for_stock_vouchers @@ -15,6 +17,8 @@ from erpnext.stock.stock_ledger import ( repost_future_sle, ) +RecoverableErrors = (JobTimeoutException, QueryDeadlockError, QueryTimeoutError) + class RepostItemValuation(Document): def validate(self): @@ -132,7 +136,7 @@ def repost(doc): doc.set_status("Completed") - except Exception: + except Exception as e: frappe.db.rollback() traceback = frappe.get_traceback() frappe.log_error(traceback) @@ -142,9 +146,9 @@ def repost(doc): message += "
" + "Traceback:
" + traceback frappe.db.set_value(doc.doctype, doc.name, "error_log", message) - notify_error_to_stock_managers(doc, message) - doc.set_status("Failed") - raise + if not isinstance(e, RecoverableErrors): + notify_error_to_stock_managers(doc, message) + doc.set_status("Failed") finally: if not frappe.flags.in_test: frappe.db.commit()