Log why request-handler unregistration fails during teardown#2573
Open
rolfheij-sil wants to merge 1 commit into
Open
Log why request-handler unregistration fails during teardown#2573rolfheij-sil wants to merge 1 commit into
rolfheij-sil wants to merge 1 commit into
Conversation
rolfheij-sil
requested review from
irahopkinson,
lyonsil and
tjcouch-sil
as code owners
July 16, 2026 19:56
At app quit, UnsubscriberAsyncList logs a bare "Unsubscriber at index N failed!" with no context when a registerCommand unregistration resolves false instead of throwing. Add logger.warn calls at each silent false-returning branch (jsonRpc unset in the network.service closure; method not locally registered or remote UNREGISTER_METHOD round-trip failed in rpc-client's unregisterMethod) so the next occurrence self-describes. No behavior change — return values, ordering, and error propagation are identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rolfheij-sil
force-pushed
the
unregister-failure-logging
branch
from
July 17, 2026 15:40
fb6f3f0 to
105fbb4
Compare
Member
Code reviewFound 1 issue:
paranext-core/src/shared/services/network.service.ts Lines 319 to 327 in 105fbb4 Documented expected-quiet-shutdown intent it contradicts: paranext-core/src/shared/services/network.service.ts Lines 112 to 115 in 105fbb4 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
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.
Summary
At every app quit, the log shows an anonymous failure with zero context:
Diagnosis: the failing unsubscriber is a
registerCommandunregistration thatresolves
falserather than throwing, and nothing in the chain logs why.The chain:
src/shared/services/network.service.ts— the unsubscriber closure returnedby
registerRequestHandlerreturnsfalseifjsonRpcis unset, or passesthrough whatever
jsonRpc.unregisterMethod(requestType)resolves.src/client/services/rpc-client.tsunregisterMethodhas three silentfalse-returning branches: the method isn't locally registered (checkedtwice, once before and once after acquiring the mutex), or the remote
UNREGISTER_METHODround-trip itself resolvedfalse.None of these branches logged anything, so
UnsubscriberAsyncListonly eversaw an opaque
falsewith no way to tell which branch fired or for whichrequest/method.
Changes
Added one
logger.warnper silent branch, each naming the request/methodtype so the log line is actionable:
network.service.ts: warn when the closure returnsfalsebecausejsonRpcis unset, and warn ifjsonRpc.unregisterMethoditself resolvedfalse.rpc-client.tsunregisterMethod: warn (matching this file's existinglogger.warnconvention for the analogousregisterMethod"alreadyregistered" branches) distinguishing "not locally registered" from "remote
unregister round-trip failed", each naming the
methodName.Behavior is unchanged — return values, ordering, and error propagation
are identical; this is purely additive logging. The underlying failure is
pre-existing and cosmetic (nothing depends on the unsubscriber succeeding at
quit-time); this PR just makes the next occurrence self-describing instead of
an anonymous index number.
Test plan
eslinton both changed files — cleantsc -p ./tsconfig.json --noEmit— no new errors (the one pre-existingerror, a missing generated
release/app/buildInfo.json, reproducesidentically on unmodified
mainand is unrelated to these files)vitest run src/shared/services/__tests__/network.service.shared-events.test.ts— 10/10 passing (no dedicated unit tests exist for
rpc-client.ts)🤖 Generated with Claude Code
Self-review — 2026-07-17 (review-paratext methodology)
Approve as-is — clean, low-risk, additive-only diagnostic logging; no behavior change. Four analysis passes (api / style / compliance / ux) per
.claude/agents/review-analyzer.md, run by a review-lead agent; author interview substituted with the PR body + PRD design records; every finding adversarially verified against code and tests.unregisterMethod's pre-mutex fast-path and post-mutex re-check log the identical message, so a log line alone can't distinguish "already gone" from "lost the race"registerMethodprecedent)Investigated separately: the "could this spam every shutdown" concern is unfounded — the new
warnlogs only fire on paths where two more-severe, pre-existing logs (console.errorinUnsubscriberAsyncList,logger.errorindeactivateExtension) already fire today.Gates:
prettier --checkpass,tsc --noEmit0 errors,eslint0 errors/warnings,vitest network.service.shared-events.test.ts10/10 pass.This change is