{"record":{"id":"2388838407f74463","repo":"DIYgod/RSSHub","slug":"the-number-of-attempts-has-exceeded-5-times","errorCode":null,"errorMessage":"The number of attempts has exceeded 5 times","messagePattern":"The number of attempts has exceeded 5 times","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/bt0/util.ts","lineNumber":9,"sourceCode":"import { CookieJar } from 'tough-cookie';\n\nimport got from '@/utils/got';\n\nconst cookieJar = new CookieJar();\n\nasync function doGot(num, host, link) {\n    if (num > 4) {\n        throw new Error('The number of attempts has exceeded 5 times');\n    }\n    const response = await got.get(link, {\n        cookieJar,\n    });\n    const data = response.data;\n    if (typeof data === 'string') {\n        const regex = /document\\.cookie\\s*=\\s*\"([^\"]*)\"/;\n        const match = data.match(regex);\n        if (!match) {\n            throw new Error('api error');\n        }\n        cookieJar.setCookieSync(match[1], host);\n        return doGot(num + 1, host, link);\n    }\n    return data;\n}\n\nconst genSize = (sizeStr) => {","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/bt0/util.ts#L1-L27","documentation":"Generic Error thrown by the recursive doGot helper after more than 5 attempts to satisfy the bt0 anti-bot cookie challenge. doGot re-requests the endpoint whenever the body is an HTML page that sets a document.cookie; if it still gets a challenge page after the 5th attempt, this guard stops the recursion.","triggerScenarios":"doGot is called with num > 4, i.e. the initial call plus 5 recursive retries all received string (HTML) bodies that set cookies but never resolved to the JSON payload. The cookie challenge loop never converges.","commonSituations":"The bt0 site changed its anti-bot mechanism so the regex no longer extracts a valid cookie; the extracted cookie is not being applied (cookieJar domain mismatch); the server keeps issuing fresh challenges for the IP; the endpoint moved.","solutions":["Open the bt0 endpoint in a browser and confirm the challenge still uses `document.cookie=\"...\"`; update the regex in doGot if the format changed.","Verify the cookieJar is applying cookies to the correct host (the `host` argument passed to setCookieSync).","Retry later — the challenge loop can be triggered by aggressive polling/rate-limiting from the server IP.","If the API moved, update _link construction in the calling route (mv.ts / tlist.ts)."],"exampleFix":"// before\nif (num > 4) {\n    throw new Error('The number of attempts has exceeded 5 times');\n}\n// after (expose the last body snippet so the regex miss is diagnosable)\nif (num > 4) {\n    throw new Error('bt0 anti-bot challenge not satisfied after 5 attempts — cookie regex may be stale');\n}","handlingStrategy":"retry","validationCode":"// Bound recursion explicitly and expose a diagnosable message:\nasync function doGot(num: number, host: string, link: string) {\n    if (num > 4) throw new Error('bt0 anti-bot challenge not satisfied after 5 attempts');\n    // ...\n}","typeGuard":null,"tryCatchPattern":"// doGot is itself the retry mechanism. From the caller, treat exhaustion as retryable:\ntry {\n    const data = await doGot(0, host, link);\n} catch (e) {\n    if (/exceeded 5 times|api error/.test((e as Error).message)) { /* retry once after delay */ }\n    throw e;\n}","preventionTips":["Keep the cookie-extraction regex in sync with bt0's anti-bot template.","Confirm the cookieJar host matches the request host so set cookies are sent back.","Rate-limit calls to bt0 to avoid triggering endless challenges."],"tags":["bt0","anti-crawl","recursion","cookie-challenge","retry-exhausted"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}