{"record":{"id":"baa938e9180b5c7b","repo":"jackwener/OpenCLI","slug":"d-msg-api-failed-baa938","errorCode":null,"errorMessage":"${d.msg || 'API failed'}","messagePattern":"\\$\\{d\\.msg \\|\\| 'API failed'\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/nowcoder/papers.js","lineNumber":30,"sourceCode":"        { name: 'limit', type: 'int', default: 10, help: 'Number of items' },\n    ],\n    columns: ['rank', 'title', 'company', 'practitioners'],\n    pipeline: [\n        { navigate: 'https://www.nowcoder.com' },\n        { evaluate: `(async () => {\n  const jobId = parseInt(\\${{ args.job | json }});\n  const companyId = \\${{ args.company | json }};\n  const limit = \\${{ args.limit }};\n  const body = {jobId, page: 1, pageSize: limit};\n  if (companyId) body.companyId = parseInt(companyId);\n  const r = await fetch('https://gw-c.nowcoder.com/api/sparta/company-question/get-paper-list', {\n    method: 'POST',\n    credentials: 'include',\n    headers: {'Content-Type': 'application/json'},\n    body: JSON.stringify(body)\n  });\n  const d = await r.json();\n  if (!d.success) throw new Error(d.msg || 'API failed');\n  return (d.data?.records || []).map((p, i) => ({\n    rank: i + 1,\n    title: p.paperName || '',\n    company: p.companyTag?.name || '',\n    practitioners: p.practiceCnt || 0,\n  }));\n})()\n` },\n        { limit: '${{ args.limit }}' },\n    ],\n});\n","sourceCodeStart":12,"sourceCodeEnd":42,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/nowcoder/papers.js#L12-L42","documentation":"The papers pipeline POSTs to nowcoder's gateway and throws new Error(d.msg || 'API failed') when the response JSON has success falsy. Since the papers list API is wrapped in the library's error handling, the resulting CommandExecutionError surfaces the server's msg or the fallback 'API failed'. This mirrors 2858 but for the company papers/practice-ranking endpoint.","triggerScenarios":"Calling the nowcoder papers command with a request body the API rejects; unauthenticated/guest session being denied; nowcoder backend returning success:false due to rate limit, maintenance, or changed request schema.","commonSituations":"Anonymous access to a members-only ranking; request payload fields renamed after a nowcoder API update; transient gateway errors during high traffic (e.g. around recruitment seasons).","solutions":["Log in first (`nowcoder login`) so credentials are included — many paper endpoints require auth","Inspect the server's msg in the error for the exact rejection reason","Retry with backoff if the message indicates rate limiting or server issues","Check that the POST body schema still matches the current API; update the pipeline if nowcoder changed it"],"exampleFix":"// before\nconst papers = await runNowcoderPapers({ company: 'bytedance' });\n// after\ntry {\n  const papers = await runNowcoderPapers({ company: 'bytedance' });\n} catch (e) {\n  if (/API failed/.test(e.message)) {\n    await runNowcoderLogin();\n    await new Promise(r => setTimeout(r, 3000));\n    return runNowcoderPapers({ company: 'bytedance' });\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://www.nowcoder.com' });\nif (!cookies.some(c => c.name === 't' && c.value)) {\n  throw new Error('Login to nowcoder before fetching papers');\n}","typeGuard":"function isApiSuccess(d) {\n  return !!d && d.success === true && Array.isArray(d.data?.records);\n}","tryCatchPattern":"try {\n  return await nowcoderPapers(query);\n} catch (e) {\n  if (/API failed/.test(e.message)) {\n    await sleep(5000);\n    return nowcoderPapers(query); // single retry with backoff\n  }\n  throw e;\n}","preventionTips":["Log in before hitting papers endpoints that require a session","Add exponential backoff around nowcoder gateway calls","Validate the POST body schema after any nowcoder API update","Log d.msg responses to diagnose success:false rejections quickly"],"tags":["api-error","post","auth","rate-limit","nowcoder"],"backgroundTag":"api-success-false","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}