justauth/JustAuth · error · AuthException

data.getString("description")

Error message

data.getString("description")

What it means

AuthDouyinRequest.checkResponse() treats a response as failed when the top-level 'message' is "error" or the nested data.error_code is non-zero, then throws AuthException(errorCode, description) with Douyin's own 'data.description' text. This guards both the token endpoint and the user-info endpoint.

Source

Thrown at src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java:80

    @Override
    public AuthResponse<AuthToken> refresh(AuthToken oldToken) {
        return AuthResponse.<AuthToken>builder()
            .code(AuthResponseStatus.SUCCESS.getCode())
            .data(getToken(refreshTokenUrl(oldToken.getRefreshToken())))
            .build();
    }

    /**
     * 检查响应内容是否正确
     *
     * @param object 请求响应内容
     */
    private void checkResponse(JSONObject object) {
        String message = object.getString("message");
        JSONObject data = object.getJSONObject("data");
        int errorCode = data.getIntValue("error_code");
        if ("error".equals(message) || errorCode != 0) {
            throw new AuthException(errorCode, data.getString("description"));
        }
    }

    /**
     * 获取token,适用于获取access_token和刷新token
     *
     * @param accessTokenUrl 实际请求token的地址
     * @return token对象
     */
    private AuthToken getToken(String accessTokenUrl) {
        String response = new HttpUtils(config.getHttpConfig()).post(accessTokenUrl).getBody();
        JSONObject object = JSONObject.parseObject(response);
        this.checkResponse(object);
        JSONObject dataObj = object.getJSONObject("data");
        return AuthToken.builder()
            .accessToken(dataObj.getString("access_token"))
            .openId(dataObj.getString("open_id"))
            .expireIn(dataObj.getIntValue("expires_in"))

View on GitHub (pinned to 694bbf1b01)

Solutions

  1. Log errorCode and description from the AuthException - Douyin's numeric codes (e.g. 2190008 for invalid client) pinpoint the cause.
  2. Confirm client_key/client_secret and that the app has passed Douyin's review for the scopes you request.
  3. Use the refresh token flow (refresh()) before calling getUserInfo() when access tokens have expired.
  4. Ensure only whitelisted test users authorize while the app is in sandbox.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    return douyinRequest.getUserInfo(token);
} catch (AuthException e) {
    log.warn("Douyin error code={}, desc={}", e.getErrorCode(), e.getErrorMsg());
    if (e.getErrorCode() != 0) {
        // map Douyin error_code to re-auth vs refresh decisions
        return errorResponse(e.getErrorCode(), e.getErrorMsg());
    }
    throw e;
}

Prevention

When it happens

Trigger: Token exchange or refresh with an invalid client_key/client_secret pair, or getUserInfo() with an access token that expired (Douyin tokens are short-lived) - Douyin returns message="error" with a non-zero data.error_code.

Common situations: Douyin open-platform app in development/trial status so only whitelected test accounts can authorize; user's token revoked when they removed the app; or the client_key changed after the app was promoted from test to production.

Related errors


AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14). Data as JSON: /api/errors/36e605b8e43f0157. Report an issue: GitHub.