From 5ca915118f5a76e647e62ee0a1827fcb28879edd Mon Sep 17 00:00:00 2001 From: Shekhar0109 Date: Sun, 28 Sep 2025 11:55:13 +0530 Subject: [PATCH 1/5] fix: handle 404 for missing Gmail labels in thread sync --- .../doctype/gmail_thread/gmail_thread.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py index 88f90ff..af9d9cf 100644 --- a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py +++ b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py @@ -262,16 +262,20 @@ def sync(user=None): .execute() ) except googleapiclient.errors.HttpError as e: - # If notFound, update historyid to the value returned by API (if any) - # You won't find history id in error, so just reset to 0 and let next sync do initial sync + skip_label = False if hasattr(e, "error_details"): for error in e.error_details: if error.get("reason") == "notFound": - gmail_account.last_historyid = 0 - gmail_account.save(ignore_permissions=True) - frappe.db.commit() - return - raise e + skip_label = True + # Label does not exist, skip it + if label_id in gmail_account.label_ids: + gmail_account.label_ids.remove(label_id) + gmail_account.save(ignore_permissions=True) + frappe.db.commit() + if skip_label: + # Skip this missing label and continue with the next one + continue # Continue outer loop for next label + raise e new_history_id = int(history.get("historyId", last_history_id)) if new_history_id > max_history_id: From a642d6b1b0b36ab48b759e5c6a31fe4617c86d8f Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Date: Mon, 16 Feb 2026 17:58:47 +0530 Subject: [PATCH 2/5] Update frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py index af9d9cf..10fbebf 100644 --- a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py +++ b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py @@ -272,6 +272,7 @@ def sync(user=None): gmail_account.label_ids.remove(label_id) gmail_account.save(ignore_permissions=True) frappe.db.commit() + break if skip_label: # Skip this missing label and continue with the next one continue # Continue outer loop for next label From fceb607b8b4ec32642ea191e8dc14cec884c14ba Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Date: Mon, 16 Feb 2026 17:59:32 +0530 Subject: [PATCH 3/5] Update frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py index 10fbebf..db4f74e 100644 --- a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py +++ b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py @@ -276,7 +276,7 @@ def sync(user=None): if skip_label: # Skip this missing label and continue with the next one continue # Continue outer loop for next label - raise e + raise e new_history_id = int(history.get("historyId", last_history_id)) if new_history_id > max_history_id: From 4f3a8ecf4ada41cd84c7f5b60b7216264153f8d5 Mon Sep 17 00:00:00 2001 From: Shashank Shekhar Date: Mon, 16 Feb 2026 18:01:15 +0530 Subject: [PATCH 4/5] Update frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py index db4f74e..15d03e6 100644 --- a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py +++ b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py @@ -275,7 +275,7 @@ def sync(user=None): break if skip_label: # Skip this missing label and continue with the next one - continue # Continue outer loop for next label + continue raise e new_history_id = int(history.get("historyId", last_history_id)) From b5e2079f2a28f9d80d9f368df78f8ebc00028621 Mon Sep 17 00:00:00 2001 From: Shekhar0109 Date: Mon, 16 Feb 2026 18:42:21 +0530 Subject: [PATCH 5/5] fix: properly distinguish between expired historyId and missing label on 404 --- .../doctype/gmail_thread/gmail_thread.py | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py index 15d03e6..bd3c4a5 100644 --- a/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py +++ b/frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_thread/gmail_thread.py @@ -262,6 +262,7 @@ def sync(user=None): .execute() ) except googleapiclient.errors.HttpError as e: + skip_label = False if hasattr(e, "error_details"): for error in e.error_details: @@ -278,6 +279,34 @@ def sync(user=None): continue raise e + if hasattr(e, "resp") and e.resp.status == 404: + try: + # Check if label still exists + gmail.users().labels().get( + userId="me", id=label_id + ).execute() + + # If label exists → historyId likely expired + gmail_account.last_historyid = 0 + gmail_account.save(ignore_permissions=True) + frappe.db.commit() + return + except googleapiclient.errors.HttpError: + # Label truly does not exist → remove it safely + removed = False + for label in getattr(gmail_account, "labels", []): + if getattr(label, "label_id", None) == label_id: + gmail_account.labels.remove(label) + removed = True + break + if removed: + gmail_account.save(ignore_permissions=True) + frappe.db.commit() + + continue + + raise + new_history_id = int(history.get("historyId", last_history_id)) if new_history_id > max_history_id: max_history_id = new_history_id @@ -411,7 +440,9 @@ def get_permission_query_conditions(user): select parent from `tabInvolved User` where account = {user} ) or `tabGmail Thread`.owner = {user} - """.format(user=frappe.db.escape(user)) + """.format( + user=frappe.db.escape(user) + ) def has_permission(doc, ptype, user):