DupFileManager, FileMonitor, RenameFile: bind the exception in retry handlers - #757
Open
johnkattenhorn wants to merge 1 commit into
Open
DupFileManager, FileMonitor, RenameFile: bind the exception in retry handlers#757johnkattenhorn wants to merge 1 commit into
johnkattenhorn wants to merge 1 commit into
Conversation
…handlers
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) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
Each retry loop in
StashPluginHelper.pyhas two exception handlers: a narrow one for connection errors, and a broad one for everything else. Both build the same log message including{e}— but only the broad handler binds the name withas e.Because the sibling handler binds
eas a function local, the narrow handler raisesUnboundLocalErrorwhile formatting its own log message. That propagates out of the retry loop, so a dropped connection — the exact condition the loop exists to survive — aborts the operation on the first failure and reports the wrong error.Reproduction, matching the structure in the source:
Scope
13 sites across the three plugins that vendor
StashPluginHelper.py:plugins/DupFileManager/StashPluginHelper.pyplugins/FileMonitor/StashPluginHelper.pyplugins/RenameFile/StashPluginHelper.pyplugins/DupFileManager/DupFileManager.pyThose are the
mergeMetadata,addTag,updateSceneanddestroySceneretry loops in each copy of the helper, plussetTagId_withRetryin DupFileManager.Every change is the same one-token edit — adding
as eto a handler that already interpolatede. No behaviour changes beyond the retry path now working as written.Testing
Tested against a clean Stash v0.31.1 instance in Docker with a two-scene library, driving the plugin helper through the real plugin entry path (plugin JSON on stdin,
server_connectioncontext).Fault injection:
mergeMetadatawas made to raiseConnectionResetErroron its first two attempts, then succeed — the scenario the retry loop is written for. Same test run against both the currentmainand this branch:mainaborts on the first reset. With the fix, the loop retries and completes as intended.Also confirmed:
mergeMetadatabetween two scenes behaves identically before and after — no regression in the success path.excepthandlers that reference an unbounde.plugins/starIdentifier/star_identifier.pymatches this pattern at first glance but is not affected —load_encodings()bindse = Exception(...)before thetry, so its handler resolves the name from the enclosing scope. Deliberately left alone.Note for maintainers
StashPluginHelper.pyis vendored into three plugins and the copies have already drifted — DupFileManager's differs from the other two. This fix is applied to all three. Worth considering whether that file wants a single shared home.LLM-assisted contribution disclosure
Per the repository's contribution policy: this change was prepared with LLM assistance (Claude). The diff has been reviewed by me, the testing described above was carried out and its results are reproduced verbatim, and I take full responsibility for the change and its license compliance.