{"record":{"id":"a9f1f8c96eeb8e1e","repo":"paascloud/paascloud-master","slug":"access-token-errcode","errorCode":null,"errorMessage":"获取access token失败, errCode:","messagePattern":"获取access token失败, errCode:","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/social/weixin/connect/WeixinOAuth2Template.java","lineNumber":126,"sourceCode":"\n\t\tlog.info(\"获取access_token, 请求URL: \" + accessTokenRequestUrl.toString());\n\n\t\tString response = getRestTemplate().getForObject(accessTokenRequestUrl.toString(), String.class);\n\n\t\tlog.info(\"获取access_token, 响应内容: \" + response);\n\n\t\tMap<String, Object> result = null;\n\t\ttry {\n\t\t\tresult = new ObjectMapper().readValue(response, Map.class);\n\t\t} catch (Exception e) {\n\t\t\tlog.error(\"getAccessToken={}\", e.getMessage(), e);\n\t\t}\n\n\t\t//返回错误码时直接返回空\n\t\tif (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {\n\t\t\tString errCode = MapUtils.getString(result, ERR_CODE);\n\t\t\tString errMsg = MapUtils.getString(result, ERR_MSG);\n\t\t\tthrow new RuntimeException(\"获取access token失败, errCode:\" + errCode + \", errMsg:\" + errMsg);\n\t\t}\n\n\t\tWeixinAccessGrant accessToken = new WeixinAccessGrant(\n\t\t\t\tMapUtils.getString(result, \"access_token\"),\n\t\t\t\tMapUtils.getString(result, \"scope\"),\n\t\t\t\tMapUtils.getString(result, \"refresh_token\"),\n\t\t\t\tMapUtils.getLong(result, \"expires_in\"));\n\n\t\taccessToken.setOpenId(MapUtils.getString(result, \"openid\"));\n\n\t\treturn accessToken;\n\t}\n\n\t/**\n\t * 构建获取授权码的请求。也就是引导用户跳转到微信的地址。\n\t *\n\t * @param parameters the parameters\n\t *","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-common/paascloud-security-core/src/main/java/com/paascloud/security/core/social/weixin/connect/WeixinOAuth2Template.java#L108-L144","documentation":"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.","triggerScenarios":"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).","commonSituations":"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'.","solutions":["Read errMsg in the exception to identify the WeChat errcode","Check appId/appSecret match the WeChat open platform/MP account","Ensure redirect_uri exactly matches the domain configured in the WeChat console","Never reuse an authorization code; redirect the user to re-authorize","Handle 42001/40013 by refreshing or re-obtaining the access token"],"exampleFix":"// before\nif (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {\n    throw new RuntimeException(\"获取access token失败, errCode:\" + errCode + \", errMsg:\" + errMsg);\n}\n// after\nif (StringUtils.isNotBlank(MapUtils.getString(result, ERR_CODE))) {\n    throw new WeixinOAuth2ApiException(Integer.parseInt(errCode), errMsg, result);\n}","handlingStrategy":"retry","validationCode":"if (authCode == null || authCode.isEmpty()) { throw new IllegalStateException(\"授权code为空,请先完成授权跳转\"); }","typeGuard":null,"tryCatchPattern":"try { grant = weixinOAuth2Template.exchangeForAccess(...); } catch (RuntimeException e) { if (e.getMessage().contains(\"40029\") || e.getMessage().contains(\"40163\")) { redirectToWechatAuth(); } else { throw e; } }","preventionTips":["Never reuse authorization codes; always redirect for a fresh one","Keep appId/appSecret in sync with the WeChat console","Whitelist the exact redirect_uri domain"],"tags":["oauth","wechat","token-exchange"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}