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

如何让Spring Converter抛出自定义异常并在服务层直接捕获?

我之前刚好碰到过这个问题!核心原因是Spring的ConversionUtils在处理转换器抛出的异常时,会把所有不属于ConversionException子类的RuntimeException都包装成ConversionFailedException。下面给你两种简单的解决办法:

方案一:让自定义异常继承Spring的ConversionException(推荐)

这是最省心的方案,直接利用Spring的内置逻辑:Spring会直接抛出ConversionException的子类,不会进行包装。

只需要修改你的ElasticSearchException,让它继承自org.springframework.core.convert.ConversionException:

import org.springframework.core.convert.ConversionException;

public class ElasticSearchException extends ConversionException {
    public ElasticSearchException(String message) {
        super(message);
    }
}

修改完成后,当你在ElasticSearchConverter中抛出ElasticSearchException时,Spring会直接把这个异常抛给服务层,不会再包装成ConversionFailedException。你在ElasticService里就能直接捕获到它了。

方案二:自定义ConversionService包装类(适用于无法修改异常继承结构的场景)

如果因为某些限制不能修改异常的继承关系,可以实现一个代理类包装Spring默认的ConversionService,在调用时还原自定义异常:

import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.stereotype.Component;

@Component
public class CustomConversionService implements ConversionService {

    private final ConversionService delegate;

    // 构造注入Spring默认的ConversionService
    public CustomConversionService(ConversionService delegate) {
        this.delegate = delegate;
    }

    @Override
    public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
        return delegate.canConvert(sourceType, targetType);
    }

    @Override
    public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
        return delegate.canConvert(sourceType, targetType);
    }

    @Override
    public <T> T convert(Object source, Class<T> targetType) {
        try {
            return delegate.convert(source, targetType);
        } catch (ConversionFailedException e) {
            // 检查异常根源是否为自定义的ElasticSearchException,是则重新抛出
            if (e.getCause() instanceof ElasticSearchException) {
                throw (ElasticSearchException) e.getCause();
            }
            // 其他异常保持原样抛出
            throw e;
        }
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        try {
            return delegate.convert(source, sourceType, targetType);
        } catch (ConversionFailedException e) {
            if (e.getCause() instanceof ElasticSearchException) {
                throw (ElasticSearchException) e.getCause();
            }
            throw e;
        }
    }
}

然后在你的服务类中注入这个自定义的CustomConversionService:

@Service
public class ElasticService {
    @Autowired
    private CustomConversionService conversionService;

    public ResponseModel getResponse(RequestModel requestModel) {
        try {
            return conversionService.convert(requestModel, ResponseModel.class);
        } catch (ElasticSearchException e) {
            // 这里就能直接捕获到自定义异常了
            // 编写你的异常处理逻辑
            throw e;
        }
    }
}

这样就能在服务层成功捕获到你自定义的ElasticSearchException了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:31:32