{"record":{"id":"26680dc2068b57b4","repo":"binarywang/WxJava","slug":"suite-token","errorCode":null,"errorMessage":"获取 suite token 失败","messagePattern":"获取 suite token 失败","errorType":"exception","errorClass":"WxRuntimeException","httpStatus":null,"severity":"critical","filePath":"weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceOkHttpImpl.java","lineNumber":83,"sourceCode":"        MediaType.get(\"application/json; charset=utf-8\"),\n        jsonBody\n      );\n\n      // 构建 POST 请求\n      Request request = new Request.Builder()\n        .url(this.configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_SUITE_TOKEN)) // URL 不包含查询参数\n        .post(requestBody) // 使用 POST 方法\n        .build();\n\n      String resultContent = null;\n      try (Response response = client.newCall(request).execute()) {\n        if (!response.isSuccessful()) {\n          throw new IOException(\"Unexpected response code: \" + response);\n        }\n        resultContent = response.body().string();\n      } catch (IOException e) {\n        log.error(\"获取 suite token 失败: {}\", e.getMessage(), e);\n        throw new WxRuntimeException(\"获取 suite token 失败\", e);\n      }\n\n      WxError error = WxError.fromJson(resultContent, WxType.CP);\n      if (error.getErrorCode() != 0) {\n        throw new WxErrorException(error);\n      }\n\n      jsonObject = GsonParser.parse(resultContent);\n      String suiteAccussToken = jsonObject.get(\"suite_access_token\").getAsString();\n      int expiresIn = jsonObject.get(\"expires_in\").getAsInt();\n      this.configStorage.updateSuiteAccessToken(suiteAccussToken, expiresIn);\n    }\n    return this.configStorage.getSuiteAccessToken();\n  }\n\n  @Override\n  public void initHttp() {\n    log.debug(\"WxCpServiceOkHttpImpl initHttp\");","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceOkHttpImpl.java#L65-L101","documentation":"Thrown as WxRuntimeException when an IOException occurs during the OkHttp suite_access_token request. The underlying IOException is wrapped with a descriptive message. This fires when the HTTP call itself fails (network-level), as opposed to error 168 which fires when the call succeeds but returns a non-zero error code.","triggerScenarios":"OkHttp client.execute() throws IOException: connection timeout to qyapi.weixin.qq.com, DNS resolution failure, TLS handshake failure, HTTP non-2xx response code (response.isSuccessful() returns false causing a manually thrown IOException).","commonSituations":"Firewall blocking outbound HTTPS; HTTP proxy misconfigured or unreachable; OkHttp client timeouts set too low; DNS resolution failure in containerized environments; WeChat API temporarily unreachable.","solutions":["Verify network connectivity: curl -v https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token","Configure adequate OkHttp timeouts: new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build()","Check firewall, proxy, and DNS settings for outbound HTTPS to qyapi.weixin.qq.com","Implement retry at the caller level — getSuiteAccessToken does not retry on IOException"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Verify network reachability before invoking suite token APIs\ntry (Socket socket = new Socket()) {\n  socket.connect(new InetSocketAddress(\"qyapi.weixin.qq.com\", 443), 5000);\n} catch (IOException e) {\n  throw new IllegalStateException(\"Cannot reach qyapi.weixin.qq.com — check network/proxy\", e);\n}","typeGuard":null,"tryCatchPattern":"// Retry at caller level since getSuiteAccessToken does not retry on IOException\nint attempts = 0;\nwhile (true) {\n  try {\n    service.getSuiteAccessToken();\n    break;\n  } catch (WxRuntimeException e) {\n    if (e.getCause() instanceof IOException && attempts++ < 3) {\n      Thread.sleep(2000L * attempts);\n      continue;\n    }\n    throw e;\n  }\n}","preventionTips":["Configure adequate OkHttp connect and read timeouts","Verify outbound HTTPS connectivity to qyapi.weixin.qq.com in your deployment environment","Check firewall, proxy, and DNS settings — especially in containerized or cloud environments","Implement retry logic at the caller level for network-level failures"],"tags":["network","io","weixin-cp","suite-access-token","okhttp","tp"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}