{"record":{"id":"2b6246b702a2306b","repo":"soimort/you-get","slug":"got-the-page-failed-s","errorCode":null,"errorMessage":"got the page failed: %s","messagePattern":"got the page failed: (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"src/you_get/extractors/lrts.py","lineNumber":47,"sourceCode":"        first_page = int(args.first)\n\n    page_size = 10\n    if ('page_size' in args and args.page_size != None):\n        page_size = int(args.page_size)\n    last_page = (total_count // page_size) + 1\n    if ('last' in args and args.last != None):\n        last_page = int(args.last)\n\n    log.i('page size is %s, page from %s to %s' % (page_size, first_page, last_page))\n    headers = {\n      'Referer': url\n    }\n    items = []\n    for page in range(first_page, last_page):\n        page_url = 'http://www.lrts.me/ajax/book/%s/%s/%s' % (book_no, page, page_size)\n        response_content = json.loads(post_content(page_url, headers))\n        if response_content['status'] != 'success':\n            raise AssertionError(\"got the page failed: %s\" % (page_url))\n        data = response_content['data']['data']\n        if data:\n            for i in data:\n                i['resName'] = parse.unquote(i['resName'])\n            items.extend(data)\n        else:\n            break\n    headers = {\n      'Referer': 'http://www.lrts.me/playlist'\n    }\n\n    for item in items:\n        i_url = 'http://www.lrts.me/ajax/path/4/%s/%s' % (item['fatherResId'], item['resId'])\n        response_content = json.loads(post_content(i_url, headers))\n        if response_content['status'] == 'success' and response_content['data']:\n            item['ok'] = True\n            item['url'] = response_content['data']\n            logging.debug('ok')","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/soimort/you-get/blob/049548f3f3f35e67ba8d3181c71fdc71d11cf260/src/you_get/extractors/lrts.py#L29-L65","documentation":"During lrts chapter enumeration the extractor POSTs to http://www.lrts.me/ajax/book/<book>/<page>/<pageSize> and expects JSON with status 'success'. Any other status (failure, auth, rate-limit) triggers AssertionError(\"got the page failed: %s\") with the failing page URL — the chapter list for that page cannot be trusted, so the run aborts.","triggerScenarios":"Requesting a page index beyond the book's real range (custom --last too large), the server rate-limiting burst POSTs, session/cookie requirements, or the AJAX endpoint schema changing so status is no longer the literal 'success'.","commonSituations":"User-supplied page_size mismatching the site's expected 10 causing out-of-range pages; hammering pagination in a loop; site adding CSRF/auth to ajax routes.","solutions":["Retry after a short delay — transient rate-limit responses commonly clear","Check the raw POST response (curl -X POST the page_url) to see the actual status/message returned","Ensure --first/--last/--page_size values stay within the book's page count derived from totalCount","If the endpoint moved or requires headers, update post_content call (URL/headers) in src/you_get/extractors/lrts.py:47"],"exampleFix":"# before\nresponse_content = json.loads(post_content(page_url, headers))\nif response_content['status'] != 'success':\n    raise AssertionError(\"got the page failed: %s\" % (page_url))\n\n# after (break instead of aborting when an out-of-range page comes back empty/failed)\nresponse_content = json.loads(post_content(page_url, headers))\nif response_content['status'] != 'success':\n    if page > 0:\n        break  # past the last page\n    raise AssertionError(\"got the page failed: %s\" % (page_url))","handlingStrategy":"retry","validationCode":"import json\n\ndef lrts_page_ok(post_fn, page_url, headers):\n    return json.loads(post_fn(page_url, headers)).get('status') == 'success'","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        lrts_download(url, ...)\n        break\n    except AssertionError as e:\n        if 'got the page failed' in str(e) and attempt < 2:\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Throttle pagination requests to avoid tripping rate limits on lrts.me/ajax","Keep --first/--last within the computed page range","Treat a failed page 0 as fatal but a failed later page as end-of-list signal"],"tags":["pagination","ajax","lrts","rate-limit"],"backgroundTag":null,"analyzedSha":"049548f3f3f35e67ba8d3181c71fdc71d11cf260","analyzedAt":"2026-08-15T03:58:15.069Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}