{"record":{"id":"672403d914498314","repo":"jackwener/OpenCLI","slug":"boss-api-request-failed-message","errorCode":null,"errorMessage":"Boss API request failed: ${message}","messagePattern":"Boss API request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/boss/utils.js","lineNumber":139,"sourceCode":"        xhr.onload = () => {\n          try { resolve(JSON.parse(xhr.responseText)); }\n          catch(e) { reject(new Error('JSON parse failed: ' + xhr.responseText.substring(0, 200))); }\n        };\n        xhr.onerror = () => reject(new Error('Network Error'));\n        xhr.ontimeout = () => reject(new Error('Timeout'));\n        xhr.send(${body ? JSON.stringify(body) : 'null'});\n      });\n    }\n  `;\n    let data;\n    try {\n        data = await page.evaluate(script);\n    } catch (error) {\n        if (error instanceof AuthRequiredError || error instanceof CommandExecutionError) {\n            throw error;\n        }\n        const message = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`Boss API request failed: ${message}`);\n    }\n    if (!data || typeof data !== 'object') {\n        throw new CommandExecutionError('Boss API returned malformed response');\n    }\n    // Auto-check auth unless caller opts out\n    if (!opts.allowNonZero && data.code !== 0) {\n        assertOk(data);\n    }\n    return data;\n}\n// ── Convenience helpers ─────────────────────────────────────────────────────\n/**\n * Fetch the boss friend (chat) list.\n */\nexport async function fetchFriendList(page, opts = {}) {\n    const pageNum = opts.pageNum ?? 1;\n    const jobId = opts.jobId ?? '0';\n    const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/getBossFriendListV2.json?page=${pageNum}&status=0&jobId=${jobId}`;","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/boss/utils.js#L121-L157","documentation":"bossFetch wraps page.evaluate's XHR promise; if the in-page promise rejects (network error, xhr.timeout, or JSON.parse failure on a non-JSON body) and the error is not already a typed library error, it is rethrown as CommandExecutionError 'Boss API request failed: <cause>'. The cause string is one of 'Network Error', 'Timeout', or 'JSON parse failed: <first 200 chars>'.","triggerScenarios":"XHR onerror (connection reset, DNS, offline browser), xhr.ontimeout after 15s (default) on a slow wapi endpoint, or a response body that isn't valid JSON (HTML anti-bot/login page) triggering the in-page parse rejection.","commonSituations":"Machine or the driven Chrome losing connectivity mid-command; BOSS serving heavy pages or slow endpoints beyond the 15s timeout; BOSS returning an HTML captcha/login interstitial instead of JSON; VPN/proxy dropping.","solutions":["Retry the command — transient network blips and slow responses often succeed on a second attempt.","Verify the driven Chrome actually has internet and the zhipin.com session (open a tab manually).","Increase the timeout by passing { timeout: 30000 } in opts if the endpoint is consistently slow.","If the cause shows 'JSON parse failed' with HTML, log in again / clear the interstitial (captcha) page in the driven Chrome, then retry.","Check VPN/proxy stability or disable it."],"exampleFix":"// before\nconst data = await bossFetch(page, url); // 15s default timeout\n// after\nconst data = await bossFetch(page, url, { timeout: 30000 }); // tolerate slow endpoints","handlingStrategy":"retry","validationCode":"async function assertOnline(page) {\n  const status = await page.evaluate(\"async () => { try { const r = await fetch('https://www.zhipin.com/favicon.ico', { method: 'HEAD' }); return r.ok; } catch { return false; } }\");\n  if (!status) throw new Error('Driven Chrome has no connectivity to zhipin.com');\n}","typeGuard":"function isTransientFetchFailure(err) {\n  return err instanceof CommandExecutionError &&\n    /Boss API request failed: (Network Error|Timeout)/.test(err.message);\n}","tryCatchPattern":"try {\n  return await bossFetch(page, url);\n} catch (e) {\n  if (isTransientFetchFailure(e)) {\n    await sleep(2000);\n    return bossFetch(page, url, { timeout: 30000 });\n  }\n  throw e;\n}","preventionTips":["Ensure the driven Chrome machine has stable connectivity before batch runs","Raise the timeout option for slow endpoints","Re-login if the cause shows 'JSON parse failed' (HTML interstitial instead of JSON)","Stabilize or disable VPN/proxy connections"],"tags":["network","timeout","json-parse","xhr"],"backgroundTag":"request-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}