From 4e81cc71221b85316e40199a22dd477458ac686f Mon Sep 17 00:00:00 2001 From: John Kattenhorn Date: Fri, 14 Aug 2026 20:17:08 +0100 Subject: [PATCH] DupFileManager, FileMonitor, RenameFile: bind the exception in retry handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each retry loop has two handlers: a narrow one for connection errors and a broad one for everything else. Both format the same message including {e}, but only the broad handler bound the name with "as e". The narrow handler raised NameError while building its own log message, which propagated out of the retry loop — so a dropped connection, the exact case the loop exists to survive, aborted the operation and reported the wrong error. Thirteen sites across the three plugins that vendor StashPluginHelper.py: the mergeMetadata, addTag, updateScene and destroyScene retry loops in each copy, plus setTagId_withRetry in DupFileManager. Reproduces on any of them: try: raise ConnectionResetError("connection dropped") except (ConnectionResetError): print(f"{e}") # NameError Verified with an AST pass over the repository: zero remaining handlers that reference an unbound e. starIdentifier's load_encodings looks like the same pattern but is correct — it binds e before the try, so it is left alone. Co-Authored-By: Claude Opus 5 (1M context) --- plugins/DupFileManager/DupFileManager.py | 2 +- plugins/DupFileManager/StashPluginHelper.py | 8 ++++---- plugins/FileMonitor/StashPluginHelper.py | 8 ++++---- plugins/RenameFile/StashPluginHelper.py | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/plugins/DupFileManager/DupFileManager.py b/plugins/DupFileManager/DupFileManager.py index 778ead52..51520485 100644 --- a/plugins/DupFileManager/DupFileManager.py +++ b/plugins/DupFileManager/DupFileManager.py @@ -348,7 +348,7 @@ def setTagId_withRetry(tagName, sceneDetails, DupFileToKeep, TagReason="", ignor if errMsg != None: stash.Warn(errMsg) return setTagId(tagName, sceneDetails, DupFileToKeep, TagReason, ignoreAutoTag) - except (requests.exceptions.ConnectionError, ConnectionResetError): + except (requests.exceptions.ConnectionError, ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"[setTagId] Exception calling setTagId. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: diff --git a/plugins/DupFileManager/StashPluginHelper.py b/plugins/DupFileManager/StashPluginHelper.py index 27bfae8e..a6f6f9e0 100644 --- a/plugins/DupFileManager/StashPluginHelper.py +++ b/plugins/DupFileManager/StashPluginHelper.py @@ -519,7 +519,7 @@ def mergeMetadata(self, SrcData, DestData, retryCount = 12, sleepSecondsBetweenR SrcData = self.find_scene(SrcData) DestData = self.find_scene(DestData) return self._mergeMetadata.merge(SrcData, DestData) - except (requests.exceptions.ConnectionError, ConnectionResetError): + except (requests.exceptions.ConnectionError, ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [mergeMetadata]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -710,7 +710,7 @@ def addTag(self, scene, tagName, tagName_descp = "", ignoreAutoTag=False, retryC dataDict.update({'tag_ids' : tagIds}) self.update_scene(dataDict) return True - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [addTag]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -745,7 +745,7 @@ def updateScene(self, update_input, create=False, retryCount = 24, sleepSecondsB if errMsg != None: self.Warn(errMsg) return self.update_scene(update_input, create) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -766,7 +766,7 @@ def destroyScene(self, scene_id, delete_file=False, retryCount = 12, sleepSecond self.Warn(f"Scene {scene_id} not found in Stash.") return False return self.destroy_scene(scene_id, delete_file) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: diff --git a/plugins/FileMonitor/StashPluginHelper.py b/plugins/FileMonitor/StashPluginHelper.py index 27406a2c..03defb7e 100644 --- a/plugins/FileMonitor/StashPluginHelper.py +++ b/plugins/FileMonitor/StashPluginHelper.py @@ -519,7 +519,7 @@ def mergeMetadata(self, SrcData, DestData, retryCount = 12, sleepSecondsBetweenR SrcData = self.find_scene(SrcData) DestData = self.find_scene(DestData) return self._mergeMetadata.merge(SrcData, DestData) - except (requests.exceptions.ConnectionError, ConnectionResetError): + except (requests.exceptions.ConnectionError, ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [mergeMetadata]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -710,7 +710,7 @@ def addTag(self, scene, tagName, tagName_descp = "", ignoreAutoTag=False, retryC dataDict.update({'tag_ids' : tagIds}) self.update_scene(dataDict) return True - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [addTag]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -745,7 +745,7 @@ def updateScene(self, update_input, create=False, retryCount = 24, sleepSecondsB if errMsg != None: self.Warn(errMsg) return self.update_scene(update_input, create) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -766,7 +766,7 @@ def destroyScene(self, scene_id, delete_file=False, retryCount = 12, sleepSecond self.Warn(f"Scene {scene_id} not found in Stash.") return False return self.destroy_scene(scene_id, delete_file) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: diff --git a/plugins/RenameFile/StashPluginHelper.py b/plugins/RenameFile/StashPluginHelper.py index 27406a2c..03defb7e 100644 --- a/plugins/RenameFile/StashPluginHelper.py +++ b/plugins/RenameFile/StashPluginHelper.py @@ -519,7 +519,7 @@ def mergeMetadata(self, SrcData, DestData, retryCount = 12, sleepSecondsBetweenR SrcData = self.find_scene(SrcData) DestData = self.find_scene(DestData) return self._mergeMetadata.merge(SrcData, DestData) - except (requests.exceptions.ConnectionError, ConnectionResetError): + except (requests.exceptions.ConnectionError, ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [mergeMetadata]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -710,7 +710,7 @@ def addTag(self, scene, tagName, tagName_descp = "", ignoreAutoTag=False, retryC dataDict.update({'tag_ids' : tagIds}) self.update_scene(dataDict) return True - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [addTag]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -745,7 +745,7 @@ def updateScene(self, update_input, create=False, retryCount = 24, sleepSecondsB if errMsg != None: self.Warn(errMsg) return self.update_scene(update_input, create) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: @@ -766,7 +766,7 @@ def destroyScene(self, scene_id, delete_file=False, retryCount = 12, sleepSecond self.Warn(f"Scene {scene_id} not found in Stash.") return False return self.destroy_scene(scene_id, delete_file) - except (ConnectionResetError): + except (ConnectionResetError) as e: tb = traceback.format_exc() errMsg = f"Exception calling [updateScene]. Will retry; count({i}); Error: {e}\nTraceBack={tb}" except Exception as e: