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

自定义ApiException无法被@ControllerAdvice异常处理器捕获的问题

为什么你的自定义ApiException没被全局异常处理器捕获?

我一眼就看到问题所在了——你的Controller层没有正确传递Service抛出的检查型异常,导致JVM把它包装成了一个RuntimeException子类,你的全局处理器自然抓不到目标异常。

先看关键的Controller代码:

@DeleteMapping("/{subjectTypeId}")
public ResponseEntity<Object> deleteSubjectType(@PathVariable int subjectTypeId) {
    subjectTypeService.deleteSubjectType(subjectTypeId);
    return ResponseEntity.ok().body(null);
}

你的Service方法deleteSubjectType明确声明了throws ApiException(这是一个检查型异常,因为它继承自Exception而非RuntimeException),但Controller调用它的时候,既没有用try-catch捕获处理,也没有在方法上声明throws ApiException。这种情况下,Java会自动把这个检查型异常包装成UndeclaredThrowableException(属于RuntimeException的子类)抛出,而你的全局异常处理器只监听ApiException类型,当然匹配不上。


两种快速解决方法,选一种适合你的:

方法1:让Controller向上抛出ApiException

直接在Controller方法上声明throws ApiException,把异常传递给全局处理器:

@DeleteMapping("/{subjectTypeId}")
public ResponseEntity<Object> deleteSubjectType(@PathVariable int subjectTypeId) throws ApiException {
    subjectTypeService.deleteSubjectType(subjectTypeId);
    return ResponseEntity.ok().body(null);
}

这样抛出的就是原始的ApiException,全局处理器的@ExceptionHandler(ApiException.class)就能精准捕获。

方法2:把ApiException改为非检查型异常

如果不想在每个Controller方法上都写throws声明,更简便的方式是让ApiException继承RuntimeException(非检查型异常,不需要显式声明抛出):

public class ApiException extends RuntimeException{ // 修改父类为RuntimeException
    private final String message;
    private final HttpStatus httpStatus;

    public ApiException(String message, HttpStatus httpStatus) {
        this.message = message;
        this.httpStatus = httpStatus;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }
}

修改后,Service和Controller都不需要再写throws ApiException,抛出的异常会直接被全局处理器捕获,这也是Spring项目中自定义异常的常用做法。

最后提个小细节:你的全局异常处理器方法handleExceptions不需要加static修饰符,Spring会把GeneralExceptionHandler作为Bean实例化,调用实例方法更符合Spring的设计习惯,建议去掉static。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:02:27