Skip to content

Fix Novelight chapter list: recover dropped chapters, refresh stale cache, correct reader labels#73

Merged
Aatricks merged 3 commits into
mainfrom
fix/novelight-chapter-pagination-gap
Jul 6, 2026
Merged

Fix Novelight chapter list: recover dropped chapters, refresh stale cache, correct reader labels#73
Aatricks merged 3 commits into
mainfrom
fix/novelight-chapter-pagination-gap

Conversation

@Aatricks

@Aatricks Aatricks commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Reading "Magic Academy's Genius Blinker" (aka "I Became a Flashing Genius at the Magic Academy") on Novelight was broken in three separate ways. This fixes all of them.

Dropped chapters

Novelight's chapter-pagination endpoint returns the last page's content for any out-of-range page instead of an empty response. The paging loop never saw an empty page, so it kept requesting pages up to the cap (about 188 extra requests per load). That flood tripped Novelight's rate limiter, which started returning 429s, and the failed pages were silently discarded. The result was a chapter list with a hole in the middle: it jumped from chapter 102 to chapter 403.

The loop now stops when a page adds no new chapters or comes back short. Failed pages are retried with backoff on 429/5xx/timeout and treated as gated (skipped) on 403. If a page inside the known range never recovers, the load fails loudly instead of saving a list with holes. Concurrency was also lowered.

Stale cached list

Chapter lists are cached per novel for 6 hours, and nothing invalidated them, so the paging fix stayed invisible on novels that were already in the library. This adds a version field to the cache entry. Entries written before the current version count as stale, which forces a one-time refetch on next open.

Wrong chapter number in the reader

Novelight reading URLs look like /book/chapter/141313, where that id is not the chapter number. The reader built its label from the URL, so it showed "Chapter 141313" while the chapter list correctly showed "Chapter 102". The reader now takes the label from the parsed chapter list when the list has a number that differs from the URL-derived one. This is a no-op for the other sources, whose URLs already contain the real chapter number.

Tests

Added unit tests for each part: retry, termination, gap-abort and gated-degrade in the paging loop; cache version staleness; and the label resolver. The usual check passes locally (unit tests, detekt, and both build flavors).

Aatricks added 3 commits July 6, 2026 11:04
Novelight's chapter-pagination endpoint clamps out-of-range pages to the
last page's content instead of returning empty, so the paging loop ran to
MAX_CHAPTER_PAGES and flooded the host, which then 429-rate-limited the real
page fetches. Those failures were silently swallowed, persisting a chapter
list with holes (e.g. jumping from ch. 102 to 403).

- Terminate paging when a page adds no new chapters (the clamp) or is short,
  instead of relying on an empty page or the page cap.
- Classify fetch results: retry 429/5xx/timeout with backoff, degrade on
  403/redirect (premium), and abort rather than persist a middle-page hole.
- Lower chapter-page concurrency and make jsonField null-safe.

Adds NovelightSourceTest coverage for retry, clamp termination, gap-abort,
and gated-degrade.
The chapter list is cached per (novel, source) for 6h, so the Novelight
paging fix stayed invisible on already-added entries until the cache
expired, and nothing (re-add or delete) invalidated it sooner. Add a
version field to the cache entry; entries written before the current
version are treated as stale, forcing a one-time refetch that heals every
existing install.
Novelight reading URLs are /book/chapter/{id} where the id is not the
chapter number, so the reader's URL-derived label showed the id (e.g.
"Chapter 141313") while the chapter list correctly showed "Chapter 102".
Prefer the chapter list's label when it carries a number that differs from
the current one, a no-op for sources whose URL already encodes the number.
@Aatricks Aatricks merged commit ef2ee8c into main Jul 6, 2026
4 checks passed
@Aatricks Aatricks deleted the fix/novelight-chapter-pagination-gap branch July 6, 2026 15:34
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