{"record":{"id":"da29c03a396a5d1c","repo":"DIYgod/RSSHub","slug":"status-code-renderdata-status-code","errorCode":null,"errorMessage":"Status code ${renderData.status_code}","messagePattern":"Status code (.+?)","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/douyin/live.ts","lineNumber":70,"sourceCode":"                const request = response.request();\n                if (request.url().includes('/webcast/room/web/enter')) {\n                    roomInfo = await response.json();\n                }\n            });\n            logger.http(`Requesting ${pageUrl}`);\n            await page.goto(pageUrl, {\n                waitUntil: 'networkidle',\n            });\n            await context.close();\n\n            return roomInfo;\n        },\n        config.cache.routeExpire,\n        false\n    );\n\n    if (renderData.status_code !== 0) {\n        throw new Error(`Status code ${renderData.status_code}`);\n    }\n\n    const roomInfo = renderData.data.data[0];\n    const roomOwner = renderData.data.user;\n    const nickname = roomOwner.nickname;\n    const userAvatar = roomOwner.avatar_thumb.url_list[0];\n\n    const items: DataItem[] = [];\n    if (roomInfo.id_str) {\n        if (roomInfo.status === 2) {\n            items.push({\n                title: `开播：${roomInfo.title}`,\n                description: `<img src=\"${roomInfo.cover.url_list[0]}\">`,\n                link: pageUrl,\n                author: nickname,\n                guid: roomInfo.id_str, // roomId is unique for each live event\n            });\n        } else if (roomInfo.status === 4) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/douyin/live.ts#L52-L88","documentation":"Thrown by the Douyin live room route when the intercepted room info API response (`/webcast/room/web/enter`) has a non-zero `status_code`. A status_code of 0 means success; any other value indicates Douyin's API rejected the request (e.g. room doesn't exist, room has been deleted, or the request was flagged as automated). The specific status code is included in the error message.","triggerScenarios":"The live room ID doesn't exist or has been deleted; Douyin's webcast API returned a rate-limit or permission error; Playwright failed to intercept the `/webcast/room/web/enter` response correctly, leaving roomInfo with an unexpected structure.","commonSituations":"User enters an outdated or incorrect room ID; the streamer's room was taken down; Douyin updated its API response format; the Playwright interception occasionally misses the response due to timing.","solutions":["Verify the room ID by visiting https://live.douyin.com/<rid> in a browser.","Retry — the route caches results, so a transient failure may resolve on cache expiry.","If the status code persists, the room likely no longer exists or is permanently unavailable.","Check Douyin API status code documentation if available (common non-zero codes indicate various error states)."],"exampleFix":"// before\nif (renderData.status_code !== 0) {\n    throw new Error(`Status code ${renderData.status_code}`);\n}\n\n// after — include more context for debugging\nif (renderData.status_code !== 0) {\n    const statusMsg = renderData.status_msg || renderData.message || 'Unknown error';\n    throw new Error(`Douyin live API error (status_code ${renderData.status_code}): ${statusMsg}`);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"interface DouyinLiveResponse {\n    status_code: number;\n    status_msg?: string;\n    data?: {\n        data: unknown[];\n        user: { nickname: string };\n    };\n}\n\nfunction isSuccessfulLiveResponse(data: unknown): data is DouyinLiveResponse {\n    return typeof data === 'object' && data !== null && (data as any).status_code === 0;\n}","tryCatchPattern":"try {\n    const feed = await fetch(`${rsshubUrl}/douyin/live/${rid}`);\n} catch (e) {\n    if (e.message.includes('Status code')) {\n        const code = e.message.match(/Status code (\\d+)/)?.[1];\n        console.error(`Douyin API returned status ${code}. Room may not exist or is restricted.`);\n        // Retry once after cache expiry\n    }\n    throw e;\n}","preventionTips":["Verify the room ID is correct and the streamer's room still exists.","Retry after cache expiry — transient API errors are common with Playwright-intercepted responses.","Be aware that Playwright interception can occasionally miss the XHR, leading to undefined renderData."],"tags":["douyin","api-error","status-code","live-streaming","playwright"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}