{"record":{"id":"5e26d628503de46e","repo":"jackwener/OpenCLI","slug":"result-message-result-error-api","errorCode":null,"errorMessage":"${result.message || result.error || 'API 请求失败'}","messagePattern":"\\$\\{result\\.message \\|\\| result\\.error \\|\\| 'API 请求失败'\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/maimai/search-talents.js","lineNumber":121,"sourceCode":"          'accept': '*/*',\n          'content-type': 'text/plain;charset=UTF-8',\n          'origin': 'https://maimai.cn',\n          'referer': 'https://maimai.cn/ent/talents/discover/search_v2',\n          'x-csrf-token': csrftoken,\n        },\n        credentials: 'include',\n        body: JSON.stringify(body),\n      });\n\n      const result = await res.json();\n\n      // Check login status\n      if (res.status === 401 || res.status === 403 || result.error_code === 20002) {\n        throw new Error('需要登录！请先在浏览器中访问 maimai.cn 并登录');\n      }\n\n      if (result.code !== 200 && result.code !== 0) {\n        throw new Error(result.message || result.error || 'API 请求失败');\n      }\n\n      return result;\n    }`);\n\n    if (!data || typeof data !== 'object' || Array.isArray(data)) {\n      throw new CommandExecutionError('Maimai search returned malformed API payload');\n    }\n\n    // Extract talent list from response. Missing list fields mean the API\n    // shape drifted; only an explicit empty array is a true empty result.\n    const talentListCandidates = [\n      data.data?.list,\n      data.data?.talent_list,\n      data.list,\n      data.talent_list,\n    ];\n    const talentList = talentListCandidates.find((value) => Array.isArray(value));","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/maimai/search-talents.js#L103-L139","documentation":"Generic fallback error thrown when the maimai search-talents API returns a non-200/non-0 business code and the response carries no message or error text. It is a plain Error thrown inside in-page JS executed by the CLI after fetching maimai.cn's search endpoint. It signals the API rejected the request in a way the client could not describe.","triggerScenarios":"fetch of the maimai search API resolves with an HTTP 200-style wrapper but result.code is neither 200 nor 0, AND result.message/result.error are both falsy.","commonSituations":"Maimai backend changes its response envelope, rate limiting or anti-bot responses returning empty bodies, expired/invalid session cookies yielding undocumented error codes.","solutions":["Re-login to maimai.cn in the browser and refresh the session cookie used by the CLI.","Retry later if rate-limited; reduce query frequency.","Log the full result object (add a console.log before the throw) to capture the undocumented code.","Update the CLI if maimai changed its API response shape."],"exampleFix":"// before\nthrow new Error(result.message || result.error || 'API 请求失败');\n// after\nconsole.error('maimai raw response:', JSON.stringify(result));\nthrow new Error(`API 请求失败 (code=${result.code})`);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function hasApiError(result) { return result && typeof result === 'object' && result.code !== 200 && result.code !== 0; }","tryCatchPattern":"try {\n  const talents = await searchTalents(query);\n} catch (e) {\n  if (/API 请求失败/.test(e.message)) {\n    console.error('maimai rejected the request; check login session and retry later');\n  } else throw e;\n}","preventionTips":["Keep the maimai.cn browser session fresh before long CLI runs.","Throttle requests to avoid anti-bot/rate-limit responses.","Log full response bodies for non-200 codes to diagnose undocumented errors."],"tags":["api","network","authentication"],"backgroundTag":"api-error-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}