{"record":{"id":"edab6e1f1cbcac45","repo":"justauth/JustAuth","slug":"object-getjsonobject-error-getstring-message-edab6e","errorCode":null,"errorMessage":"object.getJSONObject(\"error\").getString(\"message\")","messagePattern":"object\\.getJSONObject\\(\"error\"\\)\\.getString\\(\"message\"\\)","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java","lineNumber":109,"sourceCode":"\n    @Override\n    protected void checkConfig(AuthConfig config) {\n        super.checkConfig(config);\n        // facebook的回调地址必须为https的链接\n        if (AuthDefaultSource.FACEBOOK == source && !GlobalAuthUtils.isHttpsProtocol(config.getRedirectUri())) {\n            // Facebook's redirect uri must use the HTTPS protocol\n            throw new AuthException(AuthResponseStatus.ILLEGAL_REDIRECT_URI, source);\n        }\n    }\n\n    /**\n     * 检查响应内容是否正确\n     *\n     * @param object 请求响应内容\n     */\n    private void checkResponse(JSONObject object) {\n        if (object.containsKey(\"error\")) {\n            throw new AuthException(object.getJSONObject(\"error\").getString(\"message\"));\n        }\n    }\n\n    /**\n     * 返回带{@code state}参数的授权url，授权回调时会带上这个{@code state}\n     *\n     * @param state state 验证授权流程的参数，可以防止csrf\n     * @return 返回授权地址\n     */\n    @Override\n    public String authorize(String state) {\n        return UrlBuilder.fromBaseUrl(super.authorize(state))\n            .queryParam(\"scope\", this.getScopes(\",\", false, AuthScopeUtils.getDefaultScopes(AuthFacebookScope.values())))\n            .build();\n    }\n}\n","sourceCodeStart":91,"sourceCodeEnd":126,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java#L91-L126","documentation":"AuthFacebookRequest.checkResponse() throws AuthException when the Facebook Graph API response contains an 'error' object; the exception message is error.message (e.g. 'Error validating access token'). It applies to token exchange, refresh, and user-info calls alike.","triggerScenarios":"Calling any Facebook endpoint with an expired or invalidated access token, a user whose token was revoked (password change, app removal), or an app in development mode queried for a user not listed as a tester/admin.","commonSituations":"Access token passed its validity window without refresh; Facebook app still in development mode so Graph API hides most users; or long-lived token invalidated because the user changed their password.","solutions":["Read error.message: 'access token has expired' -> call refresh(); 'user changed password' or 'not authorized' -> re-run the authorize flow.","Switch the Facebook app to Live mode (or add test users) if user info fails only for non-admin accounts.","Implement token refresh before every batch of Graph calls rather than after failure.","Register a Deauthorize Callback URL in the Facebook console to drop local sessions when users remove the app."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return facebookRequest.getUserInfo(token);\n} catch (AuthException e) {\n    String m = String.valueOf(e.getErrorMsg());\n    if (m.contains(\"expired\")) {\n        return facebookRequest.refresh(AuthToken.builder().refreshToken(refreshToken).build());\n    }\n    if (m.contains(\"changed the password\") || m.contains(\"not authorized\")) {\n        return redirectToReauthorize();\n    }\n    throw e;\n}","preventionTips":["Refresh Facebook tokens before they expire instead of reacting to failures.","Put the app in Live mode (or add testers) before real-user traffic.","Configure the Deauthorize Callback so revoked users are logged out proactively."],"tags":["oauth","facebook","justauth","api-error","token-expired"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}