{"record":{"id":"7f982dbe9a609272","repo":"binarywang/WxJava","slug":"getchatdata-err-ret-ret","errorCode":null,"errorMessage":"getchatdata err ret  + ret","messagePattern":"getchatdata err ret  \\+ ret","errorType":"exception","errorClass":"WxErrorException","httpStatus":null,"severity":"error","filePath":"weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java","lineNumber":332,"sourceCode":"  }\n\n  @Override\n  public WxCpAgreeInfo checkSingleAgree(@NonNull WxCpCheckAgreeRequest checkAgreeRequest) throws WxErrorException {\n    String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(CHECK_SINGLE_AGREE);\n    String responseContent = this.cpService.postForMsgAudit(apiUrl, checkAgreeRequest.toJson());\n    return WxCpAgreeInfo.fromJson(responseContent);\n  }\n\n  @Override\n  public List<WxCpChatDatas.WxCpChatData> getChatRecords(long seq, @NonNull long limit, String proxy, String passwd,\n                                                         @NonNull long timeout) throws Exception {\n    long sdk = this.getOrInitThreadLocalSdk();\n\n    long slice = Finance.NewSlice();\n    long ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);\n    if (ret != 0) {\n      Finance.FreeSlice(slice);\n      throw new WxErrorException(\"getchatdata err ret \" + ret);\n    }\n\n    // 拉取会话存档\n    String content = Finance.GetContentFromSlice(slice);\n    Finance.FreeSlice(slice);\n    WxCpChatDatas chatDatas = WxCpChatDatas.fromJson(content);\n    if (chatDatas.getErrCode().intValue() != 0) {\n      throw new WxErrorException(chatDatas.toJson());\n    }\n\n    List<WxCpChatDatas.WxCpChatData> chatDataList = chatDatas.getChatData();\n    return chatDataList != null ? chatDataList : Collections.emptyList();\n  }\n\n  @Override\n  public WxCpChatModel getDecryptChatData(@NonNull WxCpChatDatas.WxCpChatData chatData,\n                                          @NonNull Integer pkcs1) throws Exception {\n    long sdk = this.getOrInitThreadLocalSdk();","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java#L314-L350","documentation":"Thrown when Finance.GetChatData() returns a non-zero code while fetching the chat-record list from the WeChat archive. This is the first step in the archive pipeline — it retrieves encrypted chat metadata (seq, encrypt_random_key, encrypt_chat_msg) in bulk. A non-zero return means the native SDK rejected the fetch request.","triggerScenarios":"Calling getChatRecords() with an expired or uninitialized SDK handle, an access_token that has lapsed, a seq value beyond the valid range, network/proxy failures reaching the WeChat archive endpoint, or the SDK's internal state being corrupted (e.g., after a process crash without re-init).","commonSituations":"The msgAudit access token was never obtained (msgAuditSecret not configured or wrong), the SDK handle was initialized in a previous process run and not re-created, the proxy is misconfigured for the archive endpoint, or seq was persisted from an old session and is now invalid after a gap in polling.","solutions":["Ensure the SDK is initialized via getOrInitThreadLocalSdk() with a valid msgAudit access_token before calling getChatRecords","Verify the msgAuditSecret and corpId are correct so the access_token refresh succeeds","If using a proxy, confirm the proxy can reach qyapi.weixin.qq.com","Reset seq to 0 to re-fetch from the beginning if the archived data range has shifted","Check native return code 10001 for SDK init failure, 10002 for token issues"],"exampleFix":"// before\nlong sdk = this.getOrInitThreadLocalSdk();\nlong ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);\n\n// after — verify SDK and token are valid before fetching\nlong sdk = this.getOrInitThreadLocalSdk();\nif (sdk == 0) {\n  throw new WxErrorException(\"SDK 初始化失败，请检查 access_token 和 Finance.NewSdk\");\n}\nString token = cpService.getMsgAuditAccessToken(false);\nif (StringUtils.isBlank(token)) {\n  throw new WxErrorException(\"会话存档 access_token 为空，请检查 msgAuditSecret 配置\");\n}\nlong ret = Finance.GetChatData(sdk, seq, limit, proxy, passwd, timeout, slice);","handlingStrategy":"try-catch","validationCode":"// Validate SDK state before fetching chat records\nString token = cpService.getMsgAuditAccessToken(false);\nif (StringUtils.isBlank(token)) {\n  throw new IllegalStateException(\"会话存档 access_token 不可用，请检查 msgAuditSecret\");\n}\nif (seq < 0) {\n  throw new IllegalArgumentException(\"seq 不能为负数\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  List<WxCpChatData> records = msgAuditService.getChatRecords(seq, limit, proxy, passwd, timeout);\n} catch (WxErrorException e) {\n  log.error(\"获取会话存档记录失败 seq={}: {}\", seq, e.getMessage());\n  if (e.getError().getErrorCode() == 10001 || e.getMessage().contains(\"ret 10001\")) {\n    // SDK init failure — re-initialize and retry once\n    cpService.getMsgAuditAccessToken(true);\n  }\n  throw e;\n}","preventionTips":["Ensure the msgAudit SDK is initialized with Finance.InitSdk() and a valid access_token before the first getChatRecords call","Persist the last successfully processed seq so you resume correctly after a restart","Monitor token expiry and refresh proactively rather than waiting for an error","Run the archive poller on a fixed schedule to avoid large seq gaps"],"tags":["wechat-cp","msg-audit","chat-records","finance-sdk","native","access-token"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}