You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@ControllerAdvice未正确处理ConstraintValidator抛出的自定义异常

问题原因

JSR-380(Bean Validation)校验框架会拦截isValid方法中抛出的所有异常,并将其包装成ConstraintViolationException(该类继承自RuntimeException)。所以你抛出的BadRequestException并没有直接被Spring的@ExceptionHandler捕获,而是被框架包装后变成了RuntimeException类型,因此触发了handleRuntimeException方法,消息“Unexpected exception during isValid call”就是框架包装时添加的提示。

解决方案

方案1:直接处理ConstraintViolationException,提取原始异常

在ExceptionTranslator中新增一个优先级更高的异常处理方法,专门处理ConstraintViolationException,从中提取你抛出的原始异常并复用handleBaseException的逻辑:

@ControllerAdvice
public class ExceptionTranslator {

    @ExceptionHandler(value = {BaseException.class})
    public ResponseEntity<Object> handleBaseException(BaseException ex) {
        // 原有的处理逻辑
    }

    @ExceptionHandler(value = {ConstraintViolationException.class})
    public ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex) {
        // 获取被框架包装的原始异常
        Throwable cause = ex.getCause();
        if (cause instanceof BaseException) {
            // 复用BaseException的处理逻辑
            return handleBaseException((BaseException) cause);
        }
        // 其他情况按原有RuntimeException逻辑处理
        return handleRuntimeException(ex);
    }

    @ExceptionHandler(value = {RuntimeException.class})
    protected ResponseEntity<Object> handleRuntimeException(RuntimeException ex) {
        // 原有的处理逻辑
    }
}

方案2:遵循Bean Validation标准用法,不直接抛异常

这是更规范的做法:不在isValid方法中抛出异常,而是通过ConstraintValidatorContext构建自定义校验错误信息,返回false让框架正常生成校验结果:

@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
    if (value < appConfig.getMinAmount()) {
        // 禁用默认的校验错误提示
        context.disableDefaultConstraintViolation();
        // 添加自定义错误信息(可结合国际化key)
        context.buildConstraintViolationWithTemplate(
                I18nKey.EXCEPTION.AMOUNT_SIZE + "," + appConfig.getMinAmount()
        ).addConstraintViolation();
        return false;
    }
    return true;
}

之后你可以在ExceptionTranslator中专门处理ConstraintViolationException,解析其中的约束违规信息,返回符合你格式的响应。

内容的提问来源于stack exchange,提问作者parsa faraji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:20:58