binarywang/WxJava · critical · WxRuntimeException
获取 suite token 失败
Error message
获取 suite token 失败
What it means
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.
Source
Thrown at weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpServiceOkHttpImpl.java:83
MediaType.get("application/json; charset=utf-8"),
jsonBody
);
// 构建 POST 请求
Request request = new Request.Builder()
.url(this.configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_SUITE_TOKEN)) // URL 不包含查询参数
.post(requestBody) // 使用 POST 方法
.build();
String resultContent = null;
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected response code: " + response);
}
resultContent = response.body().string();
} catch (IOException e) {
log.error("获取 suite token 失败: {}", e.getMessage(), e);
throw new WxRuntimeException("获取 suite token 失败", e);
}
WxError error = WxError.fromJson(resultContent, WxType.CP);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
jsonObject = GsonParser.parse(resultContent);
String suiteAccussToken = jsonObject.get("suite_access_token").getAsString();
int expiresIn = jsonObject.get("expires_in").getAsInt();
this.configStorage.updateSuiteAccessToken(suiteAccussToken, expiresIn);
}
return this.configStorage.getSuiteAccessToken();
}
@Override
public void initHttp() {
log.debug("WxCpServiceOkHttpImpl initHttp");View on GitHub (pinned to 1c43293a3c)
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
Defensive patterns
Strategy: retry
Validate before calling
// Verify network reachability before invoking suite token APIs
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress("qyapi.weixin.qq.com", 443), 5000);
} catch (IOException e) {
throw new IllegalStateException("Cannot reach qyapi.weixin.qq.com — check network/proxy", e);
} Try / catch
// Retry at caller level since getSuiteAccessToken does not retry on IOException
int attempts = 0;
while (true) {
try {
service.getSuiteAccessToken();
break;
} catch (WxRuntimeException e) {
if (e.getCause() instanceof IOException && attempts++ < 3) {
Thread.sleep(2000L * attempts);
continue;
}
throw e;
}
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14).
Data as JSON: /api/errors/26680dc2068b57b4.
Report an issue: GitHub.