{"record":{"id":"0d03cd912f6634a2","repo":"justauth/JustAuth","slug":"object-get-error-object-get-error-desc","errorCode":null,"errorMessage":"object.get(\"error\") + \":\" + object.get(\"error_description\")","messagePattern":"object\\.get\\(\"error\"\\) \\+ \":\" \\+ object\\.get\\(\"error_description\"\\)","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthQqRequest.java","lineNumber":91,"sourceCode":"\n    /**\n     * 获取QQ用户的OpenId，支持自定义是否启用查询unionid的功能，如果启用查询unionid的功能，\n     * 那就需要开发者先通过邮件申请unionid功能，参考链接 {@see http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D}\n     *\n     * @param authToken 通过{@link AuthQqRequest#getAccessToken(AuthCallback)}获取到的{@code authToken}\n     * @return openId\n     */\n    private String getOpenId(AuthToken authToken) {\n        String response = new HttpUtils(config.getHttpConfig()).get(UrlBuilder.fromBaseUrl(\"https://graph.qq.com/oauth2.0/me\")\n            .queryParam(\"access_token\", authToken.getAccessToken())\n            .queryParam(\"unionid\", config.isUnionId() ? 1 : 0)\n            .build()).getBody();\n        String removePrefix = response.replace(\"callback(\", \"\");\n        String removeSuffix = removePrefix.replace(\");\", \"\");\n        String openId = removeSuffix.trim();\n        JSONObject object = JSONObject.parseObject(openId);\n        if (object.containsKey(\"error\")) {\n            throw new AuthException(object.get(\"error\") + \":\" + object.get(\"error_description\"));\n        }\n        authToken.setOpenId(object.getString(\"openid\"));\n        if (object.containsKey(\"unionid\")) {\n            authToken.setUnionId(object.getString(\"unionid\"));\n        }\n        return StringUtils.isEmpty(authToken.getUnionId()) ? authToken.getOpenId() : authToken.getUnionId();\n    }\n\n    /**\n     * 返回获取userInfo的url\n     *\n     * @param authToken 用户授权token\n     * @return 返回获取userInfo的url\n     */\n    @Override\n    protected String userInfoUrl(AuthToken authToken) {\n        return UrlBuilder.fromBaseUrl(source.userInfo())\n            .queryParam(\"access_token\", authToken.getAccessToken())","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java#L73-L109","documentation":"AuthQqRequest.getOpenId throws AuthException built from 'error:error_description' when QQ's /oauth2.0/me endpoint (response stripped of the JSONP callback wrapper) contains an error key. This endpoint exchanges an access token for openid/unionid.","triggerScenarios":"getUserInfo or getOpenId running with an access token QQ has expired or invalidated (error 100016 invalid access token), or a malformed token passed in.","commonSituations":"Stored QQ token reused after expiry, token from a different QQ Connect app (appid mismatch with oauth_consumer_key), or the JSONP-stripping replace failing because QQ changed the callback format.","solutions":["Refresh the access token before calling getOpenId; QQ access tokens expire per expires_in returned at token time","Confirm config.getClientId() is the same QQ Connect appid under which the token was issued","Catch AuthException and inspect the error/error_description pair (e.g. 100016) to decide refresh vs re-login","Persist the openid/unionid after first retrieval to avoid repeated me-endpoint calls"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n    String openId = qqRequest.getOpenId(token); // via getUserInfo path\n} catch (AuthException e) {\n    if (String.valueOf(e.getMessage()).contains(\"100016\")) {\n        token = qqRequest.refresh(token).getData();\n        // retry once\n    }\n}","preventionTips":["Persist openid/unionid after first login to skip repeated me calls","Ensure the appid used for token issuance matches config.getClientId()","Refresh tokens proactively; QQ access tokens expire quickly"],"tags":["oauth","qq","openid","token-expired","auth-exception"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}