refactor(find): FF series URLs resolve through the resolver, not ff-marketplace→Raster - #100
Merged
Merged
Conversation
Three layers, one root cause. Node's happy-eyeballs gives each address-family connect attempt 250 ms — shorter than one round trip to api.raster.art from Asia (~250 ms RTT). On networks with broken IPv6 the IPv4 attempt dies mid-handshake, the IPv6 fallback has no route, and find fails or stalls with no output. - entry: raise the auto-select-family attempt timeout to 2.5 s so a transcontinental IPv4 connect is not cut off mid-handshake - raster-client: 20 s AbortSignal on every query — a stalled request becomes a fast error, never a silent hang; network failures rethrow as RasterUnreachableError naming the endpoint and the undici cause (bare 'fetch failed' says neither) - find: Raster unreachable at the coords step degrades to a one-item playlist with a warning instead of dying — Raster enriches a find, it is not required to build something playable Repro from #97 (FF series URL that hung at 90 s and 150 s) now completes: 35 items, or a fast actionable error when the network is truly down. Suite: 447/447.
feralfile-bot
approved these changes
Jul 27, 2026
feralfile-bot
left a comment
Contributor
There was a problem hiding this comment.
Reviewers: 2 (approve: 2, comment: 0, request-changes: 0).
No meaningful findings after consolidation. The series path now uses the resolver’s exact token list, retains a clear resolver-miss error, and has focused coverage for the single-edition case. This resolves the previously deferred #98 concern.
Both reviewers caught it: rasterQuery only converted failures from fetch() itself. A body that stalls or terminates after headers rejects in response.text()/response.json(), outside the boundary — so resolveCoords couldn't recognize RasterUnreachableError and never performed its promised single-token fallback. Body consumption now sits inside the boundary: a rejected read on an ok response throws RasterUnreachableError (a 200 whose body can't be read is unusable either way; falling back is right even for server-side garbage). Intentional API-level errors keep their types: an HTTP error stays a status error even when its body is unreadable (best-effort text, never masks the status), and GraphQL errors are unchanged. Tests: mid-stream termination → typed error; 502 with unreadable body → status error, not unreachable; end-to-end find run against a mock server that destroys the body → warns and degrades to a one-item playlist. 450/450.
…arketplace→Raster A Feral File series URL resolved ONE token via ff-marketplace, then asked Raster, which maps the token to its parent artwork — so a single-edition series page (e.g. 36 Points Display Edition) built the sibling collection's 35 tokens instead of the 1 the page describes. Flagged as out-of-scope in #98; this is that fix. Series URLs now route through source-resolver's Feral File site module (series slug → /api/series → /api/artworks?seriesID), exactly like shows already did — one FF resolution path for page-shaped URLs, and find builds precisely the tokens the page describes. Artwork URLs keep the coords→Raster path: a single-token page carries no series intent to preserve. Verified live: the Display Edition series URL now builds 1 item with correct provenance (was 35), in seconds (was minutes of indexer warming for tokens the user never asked about).
moskovich
force-pushed
the
refactor/ff-series-single-resolution
branch
from
July 27, 2026 13:07
f0f67a1 to
698727e
Compare
feralfile-bot
approved these changes
Jul 27, 2026
feralfile-bot
left a comment
Contributor
There was a problem hiding this comment.
Reviewers: 2 (approve: 2, comment: 0, request-changes: 0).
No meaningful findings after re-review. The series route correctly uses the resolver token-list path, preserves artwork behavior, and includes focused success and resolver-miss coverage. No PR discussion exceptions apply.
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.
Stacked on #98 (merge that first; this branch contains its commit). Closes the "noted, out of scope" item from #98.
Problem
findon a Feral File series URL resolved one token viaff-marketplace, then consulted Raster, which expands a token to its parent artwork. A single-edition series page — 36 Points Display Edition — therefore built the sibling collection's 35 tokens, plus minutes of FF-indexer warming for tokens the user never pointed at.Change
Series URLs route through the source-resolver's Feral File site module (
/api/series/{slug}→/api/artworks?seriesID=), exactly as show URLs already did. One FF resolution path for page-shaped URLs;findbuilds precisely the tokens the page describes. Artwork URLs keep the coords→Raster path — a single-token page has no series intent to preserve.resolveFeralFileToken's series branch is now unreachable fromfind; left in place (still unit-tested) rather than deleted here to keep the diff review-sized.Verification