竹简文档
异常处理

用户认证异常(仅 MVC)

UserAuthenticationException 提供携带错误类型枚举和用户信息的认证异常处理

UserAuthenticationException

UserAuthenticationException 是专门用于用户认证与授权场景的异常类,继承自 RuntimeException。该异常携带 ErrorType 枚举标识具体的认证错误类型,并可选择性地附带 UserInfo 记录类提供用户上下文信息。

ErrorType 枚举

ErrorType 定义了所有可能的认证错误类型:

字段

类型

UserInfo 记录类

UserInfo 是一个内嵌的记录类,用于在异常中携带触发认证错误的用户信息:

UserAuthenticationException.java
// 记录类,不可变且自动生成 equals/hashCode/toString
public record UserInfo(
    String userId,
    String username,
    String email
) {}

字段

类型

异常结构

UserAuthenticationException.java
public class UserAuthenticationException extends RuntimeException {

    private final ErrorType errorType;
    private final UserInfo userInfo;

    public UserAuthenticationException(ErrorType errorType, String message) {
        super(message);
        this.errorType = errorType;
        this.userInfo = null;
    }

    public UserAuthenticationException(
            ErrorType errorType, String message, UserInfo userInfo) {
        super(message);
        this.errorType = errorType;
        this.userInfo = userInfo;
    }

    // getter 方法...
}

使用示例

抛出认证异常

AuthService.java
@Service
public class AuthService {

    public TokenVO login(String username, String password) {
        UserEntity user = userMapper.findByUsername(username);

        if (user == null) {
            // 用户不存在
            throw new UserAuthenticationException(
                ErrorType.USER_NOT_EXIST, "用户不存在"
            );
        }

        if (user.isBanned()) {
            // 用户已封禁,附带用户信息
            throw new UserAuthenticationException(
                ErrorType.USER_BANNED, "账户已被封禁",
                new UserInfo(user.getId(), user.getUsername(), user.getEmail())
            );
        }

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new UserAuthenticationException(
                ErrorType.WRONG_PASSWORD, "密码错误"
            );
        }

        return generateToken(user);
    }
}

令牌校验

TokenFilter.java
public class TokenFilter {

    public void validateToken(String token) {
        if (token == null || token.isEmpty()) {
            throw new UserAuthenticationException(
                ErrorType.USER_NOT_LOGIN, "请先登录"
            );
        }

        if (tokenService.isExpired(token)) {
            throw new UserAuthenticationException(
                ErrorType.TOKEN_EXPIRED, "登录已过期,请重新登录"
            );
        }
    }
}

权限校验

PermissionService.java
public void checkPermission(String userId, String resource) {
    if (!hasPermission(userId, resource)) {
        throw new UserAuthenticationException(
            ErrorType.PERMISSION_DENIED, "无权访问该资源"
        );
    }
}

异常处理

UserAuthenticationException 由异常处理器捕获并转换为标准响应:

response.json
{
  "context": "550e8400-e29b-41d4-a716-446655440000",
  "output": "UNAUTHORIZED",
  "code": 40101,
  "message": null,
  "errorMessage": "登录已过期,请重新登录",
  "duration": 3,
  "data": null
}

HTTP 状态码为 401(40101 / 100)。

下一步

On this page