paascloud/paascloud-master · error · RuntimeException

获取access token失败, errCode:

Error message

获取access token失败, errCode:

What it means

WeixinOAuth2Template.getAccessToken posts to WeChat's OAuth token endpoint and inspects the JSON response. When the response contains an `errcode` field, WeChat rejected the request and the template throws a RuntimeException carrying errCode and errMsg.

Solutions

  1. Read errMsg in the exception to identify the WeChat errcode
  2. Check appId/appSecret match the WeChat open platform/MP account
  3. Ensure redirect_uri exactly matches the domain configured in the WeChat console
  4. Never reuse an authorization code; redirect the user to re-authorize
  5. Handle 42001/40013 by refreshing or re-obtaining the access token

Example fix

// before
if (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {
    throw new RuntimeException("获取access token失败, errCode:" + errCode + ", errMsg:" + errMsg);
}
// after
if (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {
    throw new WeixinOAuth2ApiException(Integer.parseInt(errCode), errMsg, result);
}
Defensive patterns

Strategy: retry

Validate before calling

if (authCode == null || authCode.isEmpty()) { throw new IllegalStateException("授权code为空,请先完成授权跳转"); }

Try / catch

try { grant = weixinOAuth2Template.exchangeForAccess(...); } catch (RuntimeException e) { if (e.getMessage().contains("40029") || e.getMessage().contains("40163")) { redirectToWechatAuth(); } else { throw e; } }

Prevention

When it happens

Trigger: Exchanging a code for an access token, or refreshing a token, when WeChat responds with errcode (e.g. 40029 invalid code, 40163 code already used, 42001 token expired).

Common situations: Authorization code replayed or expired (codes are single-use, ~5 min TTL); wrong appid/secret; redirect_uri not whitelisted in WeChat MP console; clock skew causing 'code been used'.

Related errors


AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10). Data as JSON: /api/errors/a9f1f8c96eeb8e1e. Report an issue: GitHub.

Appendix: source

Thrown at paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/social/weixin/connect/WeixinOAuth2Template.java:126

		log.info("获取access_token, 请求URL: " + accessTokenRequestUrl.toString());

		String response = getRestTemplate().getForObject(accessTokenRequestUrl.toString(), String.class);

		log.info("获取access_token, 响应内容: " + response);

		Map<String, Object> result = null;
		try {
			result = new ObjectMapper().readValue(response, Map.class);
		} catch (Exception e) {
			log.error("getAccessToken={}", e.getMessage(), e);
		}

		//返回错误码时直接返回空
		if (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {
			String errCode = MapUtils.getString(result, ERR_CODE);
			String errMsg = MapUtils.getString(result, ERR_MSG);
			throw new RuntimeException("获取access token失败, errCode:" + errCode + ", errMsg:" + errMsg);
		}

		WeixinAccessGrant accessToken = new WeixinAccessGrant(
				MapUtils.getString(result, "access_token"),
				MapUtils.getString(result, "scope"),
				MapUtils.getString(result, "refresh_token"),
				MapUtils.getLong(result, "expires_in"));

		accessToken.setOpenId(MapUtils.getString(result, "openid"));

		return accessToken;
	}

	/**
	 * 构建获取授权码的请求。也就是引导用户跳转到微信的地址。
	 *
	 * @param parameters the parameters
	 *

View on GitHub (pinned to 781281a950)