Skip to content

fix: list subscriptions through v2 and paginate the method that was called - #11

Merged
gastonrey merged 2 commits into
mainfrom
fix/subscriptions-list-and-pagination
Aug 21, 2026
Merged

fix: list subscriptions through v2 and paginate the method that was called#11
gastonrey merged 2 commits into
mainfrom
fix/subscriptions-list-and-pagination

Conversation

@gastonrey

Copy link
Copy Markdown
Collaborator

Both of these are listed as Known issues in the 0.2.1 changelog. One of them is worse than
recorded, and the example covering it was asserting the bug.

#list always raised

Subscriptions#list used base_path, which is /v1/subscriptions — a route that does not
exist. Verified against the sandbox:

subscriptions.list  ->  NotFoundError 404: Route not found

The changelog described this as "uses the v1 path while #get/#update and search use v2",
which reads like an inconsistency. It is a method that could never return.

base_path stays on v1, because the action sub-paths genuinely live there: POST /v1/subscriptions/{id}/update is what the API accepts, and so are cancel, pause,
activate, reactivate, reinstate and renew. Moving base_path wholesale breaks 21
examples. Only the collection GET moves, onto the same search_path that search already uses.

The existing example stubbed /v1/subscriptions, so it passed whether or not the endpoint
existed — the same failure mode as the update_operation payload corrected in #10: a stub
validating a shape nobody had checked against the API.

#next_page left the endpoint it came from

Collection#next_page re-issued @resource.list regardless of which method produced the page,
so a page from a custom list method paged into the resource's default endpoint. Today
Subscriptions#list_templates is the only such method, and the endpoint it would have jumped to
is the 404 above.

Collection now takes the method that produced it, defaulting to :list, and next_page calls
that. Existing callers are unaffected.

Verification

  • 110 examples, up from 105. RuboCop clean across 35 files.
  • New collection_spec.rb covers the default path, the custom-method path, the last page, and
    auto_paginate over a custom method.
  • Three mutations, three caught: next_page back to the default list (2 failures), list back
    to resource_path (1), and base_path moved to v2 (21 — which is the evidence for leaving it
    alone).
  • Live against the sandbox with this branch loaded: list returns 29 subscriptions,
    next_page returns a disjoint page, auto_paginate walks all 29, and list_templates
    answers 0 rows with next_page nil instead of reaching for another endpoint.

A correction

An earlier read of this claimed list_templates(...).next_page raised NoMethodError. It does
not: the sandbox has zero templates, so next_page correctly returned nil and the probe called
.data on it. The pagination bug here is the wrong-endpoint one above, pinned by a spec rather
than by a live reproduction.

Still open, not in this PR

  • The write retry budget is a hardcoded MAX_WRITE_RETRIES = 2 while Configuration already
    carries max_retries for the read retry — two budgets, one unreachable.
  • push_hyperline_catalog.rb in the monolith still monkey-patches BaseResource#request,
    because it needs a hard timeout, retries on 404 and 409, poison detection, and nonce-carrying
    keys. Until retry policy is configurable here, any signature change in this gem breaks that
    script silently — which is exactly what feat: write safety, error classes, and the Features resource #10 did.

…alled

Two bugs the 0.2.1 changelog listed as known issues, one of which was worse than
recorded.

`#list` used base_path, which is `/v1/subscriptions` -- a route that does not
exist. It answers 404 "Route not found", so the method always raised and the
"inconsistent with get/update" note undersold it. base_path stays on v1 because
the action sub-paths genuinely live there: POST /v1/subscriptions/{id}/update is
what the API accepts, and so are cancel, pause, activate and the rest. Only the
collection GET moves.

The existing example stubbed `/v1/subscriptions`, so it asserted the bug rather
than the behaviour and passed either way.

`Collection#next_page` re-issued the resource's default `#list` no matter which
method had produced the page, so a page from a custom one -- Subscriptions
#list_templates is the only current case -- paged into the wrong endpoint. For
subscriptions that endpoint was the 404 above. Collection now remembers the
method it came from.

Verified against the sandbox: list returns 29 subscriptions, next_page returns a
disjoint page, auto_paginate walks all 29, and list_templates answers 0 rows with
next_page nil rather than reaching for another endpoint.
@gastonrey
gastonrey marked this pull request as ready for review August 21, 2026 14:29
Two PRs have landed since 0.2.1 without a changelog entry, and the "Known issues"
list under 0.2.1 documents the two bugs the previous commit fixes -- so as it
stands the file tells the next reader that a method which now works still cannot
return.

0.2.1 keeps its list unchanged: it was accurate for that release. The Unreleased
section says which of them are fixed, and carries the API contracts that were
established against the sandbox rather than inferred -- archive-before-delete,
PUT rather than POST for archiving, and the bare array from the product-features
endpoint -- because none of them are in Hyperline's docs.

The remaining known issue is the one this run did not solve: retry policy is a
constant here and configuration there, which is why a consumer needing a hard
timeout or a retry on 404 still wraps #request itself.
@gastonrey
gastonrey merged commit 073f3b9 into main Aug 21, 2026
1 check 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