Skip to content

[fix] Isolate registry/package failures during sync instead of crashing - #95

Merged
kmturley merged 1 commit into
mainfrom
fix/sync-registry-errors
Jul 30, 2026
Merged

[fix] Isolate registry/package failures during sync instead of crashing#95
kmturley merged 1 commit into
mainfrom
fix/sync-registry-errors

Conversation

@kmturley

Copy link
Copy Markdown
Member

Summary

  • Manager.sync() called addPackage() once per whole registry package list and once per registry fetch, both unprotected: a single unreachable/misconfigured registry, or a single malformed package version anywhere in any registry's response, threw and aborted the entire sync — including every other registry and package not yet processed. This is the remaining half of the "validation throws crash sync/scan" finding from an internal spec-compliance audit (the scan() side was already fixed in [fix] Discover unsupported packages during scan instead of ignoring them #92).
  • sync() now processes one package version at a time, catching and recording failures — both per-registry fetch failures and per-version validation failures — into a new syncErrors list (getSyncErrors()) instead of throwing, so the rest of the sync continues.
  • Updated specification.md's Sync logic to describe this.
  • Found and fixed a related pre-existing bug in addPackage() while testing this: it registered a brand-new Package into the index before attempting to add its versions, so when addVersion() threw (now actually observable, since sync() catches it instead of crashing first), an empty, orphaned Package was left behind in the index for a package that was never really added — getPackage() would return a defined-but-empty object instead of undefined. addPackage() now only registers a newly-created package after its versions have been added successfully.

Test plan

  • npm run check passes (format, lint, build, tests — 193/193)
  • New tests: an unreachable registry (example.invalid, RFC 2606 reserved) doesn't abort syncing the other, reachable registry; a malformed package version (mocked registry response) is isolated and recorded in getSyncErrors() without affecting a sibling valid package

🤖 Generated with Claude Code

Manager.sync() called addPackage() once per whole registry package
list and once per registry fetch, both unprotected: a single
unreachable/misconfigured registry, or a single malformed package
version anywhere in any registry's response, threw and aborted the
entire sync - including every other registry and package not yet
processed. This is the remaining half of the "validation throws crash
sync/scan" finding from an internal spec-compliance audit (the scan()
side was already fixed separately).

sync() now processes one package version at a time, catching and
recording failures (both per-registry fetch failures and per-version
validation failures) into a new syncErrors list (getSyncErrors())
instead of throwing, so the rest of the sync can continue.

While testing this, found and fixed a related pre-existing bug in
addPackage(): it registered a brand-new Package into the index before
attempting to add its versions, so when addVersion() threw (now
reachable/observable now that sync() catches it instead of crashing
first), an empty, orphaned Package was left behind in the index for a
package that was never actually added. addPackage() now only registers
a newly-created package after its versions have been added
successfully.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@kmturley
kmturley merged commit 859c4a1 into main Jul 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant