{"record":{"id":"bbc1cd2c37393651","repo":"lyswhut/lx-music-desktop","slug":"error-bbc1cd","errorCode":null,"errorMessage":"获取热搜词失败","messagePattern":"获取热搜词失败","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/renderer/utils/musicSdk/wy/hotSearch.js","lineNumber":13,"sourceCode":"import { eapiRequest } from './utils/index'\n\nexport default {\n  _requestObj: null,\n  async getList(retryNum = 0) {\n    if (this._requestObj) this._requestObj.cancelHttp()\n    if (retryNum > 2) return Promise.reject(new Error('try max num'))\n\n    const _requestObj = eapiRequest('/api/search/chart/detail', {\n      id: 'HOT_SEARCH_SONG#@#',\n    })\n    const { body, statusCode } = await _requestObj.promise\n    if (statusCode != 200 || body.code !== 200) throw new Error('获取热搜词失败')\n\n    return { source: 'wy', list: this.filterList(body.data.itemList) }\n  },\n  filterList(rawList) {\n    return rawList.map(item => item.searchWord)\n  },\n}\n","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/lyswhut/lx-music-desktop/blob/9c364b482e5621a1d38b50e8610d2fb974457e6e/src/renderer/utils/musicSdk/wy/hotSearch.js#L1-L21","documentation":"Thrown by Netease's hotSearch.getList when the eapi-encrypted endpoint /api/search/chart/detail returns non-200 or body.code !== 200. Uses eapiRequest (Netease's eapi encryption wrapper, different from weapi) with a fixed parameter id: 'HOT_SEARCH_SONG#@#'. Has a retry guard (retryNum > 2) that fires first. Reads body.data.itemList.","triggerScenarios":"The eapi encryption is broken (Netease updates their eapi key/algorithm). The search chart endpoint is deprecated or the id 'HOT_SEARCH_SONG#@#' changes. Rate-limiting or IP-banning. Network interference with music.163.com.","commonSituations":"Netease rotates their eapi encryption secrets, breaking all eapi requests. Non-CN IP blocking. The hot search chart ID format changes. Unlike weapi, eapi failures are often silent (returns non-200 rather than an error code), making diagnosis harder.","solutions":["Log body and statusCode to diagnose encryption vs. rate-limiting.","Verify the eapi encryption is current by testing other eapi endpoints.","Retry by calling getList(retryNum + 1) since it supports bounded retries.","Fall back to another provider's hot search if Netease is unavailable.","Use a CN proxy if running from outside China."],"exampleFix":"// before\nconst { body, statusCode } = await _requestObj.promise\nif (statusCode != 200 || body.code !== 200) throw new Error('获取热搜词失败')\n\n// after\nconst { body, statusCode } = await _requestObj.promise\nif (statusCode != 200 || !body || body.code !== 200) {\n  console.warn('wy hotSearch failed', { statusCode, code: body?.code })\n  if (retryNum < 2) return this.getList(retryNum + 1)\n  throw new Error('获取热搜词失败')\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isWyHotSearchResponse(body) {\n  return body != null && typeof body === 'object' && body.code === 200 && body.data != null && Array.isArray(body.data.itemList)\n}","tryCatchPattern":"try {\n  const result = await wyHotSearch.getList()\n} catch (err) {\n  if (err.message === '获取热搜词失败') {\n    console.warn('Netease hot search unavailable (check eapi keys / IP blocking)')\n    return { source: 'wy', list: [] }\n  }\n  throw err\n}","preventionTips":["Call getList with a retryNum parameter to leverage built-in retries.","Keep eapi encryption keys updated — Netease rotates them separately from weapi.","Fall back to another provider's hot search if Netease is unavailable.","Use a CN proxy if running from outside China.","Log body and statusCode to diagnose encryption vs. rate-limiting."],"tags":["netease","hot-search","network","api-contract","eapi-encryption","https","rate-limiting"],"backgroundTag":null,"analyzedSha":"9c364b482e5621a1d38b50e8610d2fb974457e6e","analyzedAt":"2026-08-12T15:14:48.244Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}