fix(registry): retry transient registry-server faults - #109
Merged
Conversation
Last night's nightly publish: 48 succeeded, 9 skipped, and one `npm/preact@latest: fetch failed` exited the run non-zero. A single dropped connection out of ~58 packages fails the whole job and leaves the registry a day stale. `version-check.ts` already retries public-registry calls with backoff, but the two fetches to our own server had none. Both now go through the same p-retry pattern: 5xx and network faults retry, 4xx aborts immediately since that is the server's considered answer. Publishing is idempotent — the server keys on registry/name/version — so a retry after a dropped connection overwrites rather than duplicating. Error messages now carry the server's response body on both paths; the existence check previously discarded it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NBQQpA86yYzwJUiVz8ph2R
|
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.
Last night's nightly publish (run #165):
One dropped connection out of ~58 packages exits the run non-zero and leaves the registry a day stale. This is the second distinct cause of a red nightly this week — the first was a broken package definition (fixed in #105), and it was worth waiting to see what the next failure looked like before deciding how to harden the job.
The gap
version-check.tsalready retries public-registry calls with exponential backoff viap-retry. The two fetches to our own registry server, inpublish.ts, had no retry at all — so a transient fault on either the existence check or the upload killed the package, and with it the run.Both now go through the same pattern: 5xx and network faults retry, 4xx aborts immediately because that is the server's considered answer rather than a blip. No new dependency;
p-retryis already used a file away.Publishing is safe to retry — the server keys on
registry/name/version, so a retry after a dropped connection overwrites rather than duplicating.Why not just stop failing the run
I considered making
publish-allexit zero when some packages succeed, and rejected it. The pipeline reported the lucia breakage correctly for five straight nights; nobody was watching. Exiting zero would mean a genuinely broken definition is never noticed at all — trading a loud, fixable failure for silent rot. Retrying the transient class while still failing loudly on the permanent class targets the actual problem.Verification
Against a local server that drops the first two connections and then answers:
Both new tests are mutation-verified: setting
retries: 0fails only the retry test; removing theAbortErrorbranch fails only the 4xx test (it hangs through the full backoff, then throws the wrong shape).Error messages also now carry the server's response body on both paths — the existence check previously discarded it, which is what turned this outage into the bare string "fetch failed".
No changeset —
@neuledge/registryisprivate: true.Generated by Claude Code