{"record":{"id":"ef4cc5dd7b461990","repo":"justauth/JustAuth","slug":"object-getstring-sub-error-object-getst","errorCode":null,"errorMessage":"object.getString(\"sub_error\") + \":\" + object.getString(\"error_description\")","messagePattern":"object\\.getString\\(\"sub_error\"\\) \\+ \":\" \\+ object\\.getString\\(\"error_description\"\\)","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java","lineNumber":183,"sourceCode":"     * @return AuthUserGender\n     */\n    private AuthUserGender getRealGender(JSONObject object) {\n        int genderCodeInt = object.getIntValue(\"gender\");\n        String genderCode = genderCodeInt == 1 ? \"0\" : (genderCodeInt == 0) ? \"1\" : genderCodeInt + \"\";\n        return AuthUserGender.getRealGender(genderCode);\n    }\n\n    /**\n     * 校验响应结果\n     *\n     * @param object 接口返回的结果\n     */\n    private void checkResponse(JSONObject object) {\n        if (object.containsKey(\"NSP_STATUS\")) {\n            throw new AuthException(object.getString(\"error\"));\n        }\n        if (object.containsKey(\"error\")) {\n            throw new AuthException(object.getString(\"sub_error\") + \":\" + object.getString(\"error_description\"));\n        }\n    }\n}\n","sourceCodeStart":165,"sourceCodeEnd":187,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java#L165-L187","documentation":"Second branch of AuthHuaweiRequest.checkResponse(): for userinfo/token errors Huawei returns a standard OAuth2 envelope with 'error', 'sub_error' and 'error_description'; this code throws AuthException whose message concatenates sub_error + ':' + error_description (e.g. '2037:The token is expired').","triggerScenarios":"getUserInfo() or token refresh when the Huawei access token has expired or been revoked, or when the granted scopes do not cover the requested user profile - Huawei returns error plus sub_error codes.","commonSituations":"Huawei access tokens are short-lived (about 1 hour) and sessions that skip refresh hit the expiry; users revoking the app in Huawei ID settings; requesting profile fields (e.g. phone/email) without the corresponding scope approved.","solutions":["Split the message on ':' - the numeric left side is Huawei's sub_error code (2037/2036 = token problems) to drive refresh-vs-reauthorize logic.","Call refresh() with the stored refresh token when sub_error indicates expiry, then retry the user-info call.","Only request scopes that are approved in App Gallery Connect, and re-run authorization after new scopes are granted.","Drop local sessions and re-authorize when the error indicates the grant was revoked."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return huaweiRequest.getUserInfo(token);\n} catch (AuthException e) {\n    String m = String.valueOf(e.getErrorMsg());\n    if (m.startsWith(\"2037\") || m.contains(\"expired\")) {\n        return huaweiRequest.refresh(AuthToken.builder().refreshToken(refreshToken).build());\n    }\n    throw e;\n}","preventionTips":["Parse Huawei sub_error codes (the number before ':') and route 2036/2037 to refresh, others to re-authorize.","Huawei access tokens last about 1 hour - refresh proactively in long sessions.","Request only console-approved scopes; re-run authorization after new scopes are granted."],"tags":["oauth","huawei","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"}