{"record":{"id":"7ab6911a23c57650","repo":"justauth/JustAuth","slug":"authtoutiaoerrorcode-geterrorcode-error-code-ge","errorCode":null,"errorMessage":"${AuthToutiaoErrorCode.getErrorCode(error_code).getDesc()}","messagePattern":"\\$\\{AuthToutiaoErrorCode\\.getErrorCode\\(error_code\\)\\.getDesc\\(\\)\\}","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java","lineNumber":127,"sourceCode":"     * @param authToken 用户授权后的token\n     * @return 返回获取userInfo的url\n     */\n    @Override\n    protected String userInfoUrl(AuthToken authToken) {\n        return UrlBuilder.fromBaseUrl(source.userInfo())\n            .queryParam(\"client_key\", config.getClientId())\n            .queryParam(\"access_token\", authToken.getAccessToken())\n            .build();\n    }\n\n    /**\n     * 检查响应内容是否正确\n     *\n     * @param object 请求响应内容\n     */\n    private void checkResponse(JSONObject object) {\n        if (object.containsKey(\"error_code\")) {\n            throw new AuthException(AuthToutiaoErrorCode.getErrorCode(object.getIntValue(\"error_code\")).getDesc());\n        }\n    }\n}\n","sourceCodeStart":109,"sourceCodeEnd":131,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java#L109-L131","documentation":"AuthToutiaoRequest.checkResponse throws AuthException when the response contains `error_code`; the message is the human description obtained by mapping the numeric code through AuthToutiaoErrorCode.getErrorCode(code).getDesc(). So the thrown text is a JustAuth-local, friendly description of the Toutiao (ByteDance) error code, not the raw server text.","triggerScenarios":"Toutiao/Douyin open-platform API calls failing: getAccessToken with an invalid or expired authorization code (code already used), getUserInfo with an expired access_token, or wrong client_key/client_secret in AuthConfig.","commonSituations":"Authorization code older than ~5 minutes or exchanged twice (double callback); app credentials rotated on the open platform; access token past its 24h-ish validity being reused; missing approved scope for the user-info API.","solutions":["Match the description against AuthToutiaoErrorCode entries (e.g. 'code 已被使用' / 'access_token 过期') to identify which token/code is at fault.","Guarantee single use of the authorization code: dedupe callback requests by code value before calling getAccessToken.","Re-run authorize(state) and re-consent when access_token has expired — Toutiao tokens are short-lived.","Verify client_key/client_secret and the applied-for scopes in the Toutiao open platform console."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// dedupe the callback code before exchange (Toutiao codes are single-use, ~5 min)\nif (!seenCodes.putIfAbsent(callback.getCode(), true)) {\n    return cachedUserFor(callback.getCode()); // or 409\n}","typeGuard":null,"tryCatchPattern":"try {\n    AuthUser u = toutiaoRequest.getUserInfo(token);\n} catch (AuthException e) {\n    log.warn(\"Toutiao error: {}\", e.getMessage()); // description from AuthToutiaoErrorCode\n    redirect(toutiaoRequest.authorize(freshState())); // code/token expired → re-consent\n}","preventionTips":["Make the OAuth callback idempotent keyed on the code parameter.","Store token expiry and re-auth before access_token lapses (short-lived).","Keep client_key/secret in env config and rotate during maintenance windows."],"tags":["justauth","toutiao","bytedance","oauth","api-error"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}