{"record":{"id":"f4b1321ff9491ff1","repo":"yikart/AiToEarn","slug":"err-instanceof-error-err-message-s","errorCode":null,"errorMessage":"解析响应数据失败: ${err instanceof Error ? err.message : String(err)}","messagePattern":"解析响应数据失败: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"project/aitoearn-electron/electron/plat/douyin/index.ts","lineNumber":2369,"sourceCode":"\n          throw new Error(\n            '服务器多次返回空数据，请检查网络连接或抖音服务器状态',\n          );\n        }\n\n        try {\n          const result = JSON.parse(responseText);\n\n          if (!result) {\n            console.error(`解析后的数据为空`);\n            throw new Error('解析后的数据为空');\n          }\n\n          return result;\n        } catch (err) {\n          console.error(`解析响应数据失败:`, err);\n          console.error(`导致错误的原始数据:`, responseText);\n          throw new Error(\n            `解析响应数据失败: ${err instanceof Error ? err.message : String(err)}`,\n          );\n        }\n      } catch (error) {\n        if (retryCount < maxRetries - 1) {\n          retryCount++;\n          console.log(\n            `请求失败，${retryDelay / 1000}秒后进行第${retryCount}次重试...`,\n          );\n          await new Promise((resolve) => setTimeout(resolve, retryDelay));\n          continue;\n        }\n\n        console.error(`请求发生错误:`, error);\n        throw new Error(\n          `请求失败: ${error instanceof Error ? error.message : String(error)}`,\n        );\n      }","sourceCodeStart":2351,"sourceCodeEnd":2387,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-electron/electron/plat/douyin/index.ts#L2351-L2387","documentation":"If responseText is non-empty but JSON.parse throws (malformed JSON, HTML error page, truncated body), the inner catch logs the raw data and rethrows as '解析响应数据失败: <original message>' (project/aitoearn-electron/electron/plat/douyin/index.ts:2369). The outer catch may retry it; on the final attempt the message is additionally wrapped as '请求失败: 解析响应数据失败: ...'. It indicates Douyin (or an intermediary) returned a non-JSON body.","triggerScenarios":"Any postFormData call where Douyin responds with HTML (e.g. a login/captcha/risk-control page), a truncated body, or garbled encoding instead of JSON — the parse throws SyntaxError which is rethrown with this prefix.","commonSituations":"Expired cookie causing Douyin to serve an HTML login/verification page instead of the JSON API response; a captive portal or proxy injecting HTML; CDN/server returning a compressed or corrupted body; endpoint URL changes after a Douyin API version bump.","solutions":["Inspect the console.error output '导致错误的原始数据:' to see the raw body — if it is HTML, refresh the Douyin cookie or complete verification (captcha/QR login).","Refresh the Douyin session cookie and re-run the operation.","Check whether the request is going through a proxy/captive portal that injects HTML, and bypass it.","Retry with backoff for transient truncation; verify the endpoint URL is still current after Douyin API updates."],"exampleFix":"// before\nconst res = await douyinService.somePostFormDataOp(cookie, data);\n// after\ntry {\n  const res = await douyinService.somePostFormDataOp(cookie, data);\n} catch (e) {\n  if (String(e.message).startsWith('解析响应数据失败')) {\n    // raw body was logged; refresh cookie or handle HTML/captcha page\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isJsonObject(text: string): boolean {\n  try {\n    const v = JSON.parse(text);\n    return typeof v === 'object' && v !== null;\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  const result = await douyinService.someOp(cookie, data);\n} catch (e) {\n  const msg = String(e.message);\n  if (msg.startsWith('解析响应数据失败') || msg.includes('解析响应数据失败')) {\n    // raw body was logged via console.error; if HTML → refresh cookie / handle captcha\n    await refreshDouyinCookie();\n  } else throw e;\n}","preventionTips":["Treat an HTML response as an auth/captcha signal and refresh cookies promptly.","Bypass corporate proxies/captive portals for creator.douyin.com traffic.","Confirm endpoint URLs are still valid after Douyin API updates.","Keep the console.error raw-body logs enabled in non-production runs for diagnosis."],"tags":["douyin","json-parse","html-response","api"],"backgroundTag":"invalid-json-response","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}