Spring Boot中@ExceptionHandler无法处理自定义异常求助
问题诊断与修复方案
1. 自定义异常继承类错误
你的AuthServerException继承了NullPointerException,这是不合理的:NullPointerException是JDK定义的空指针专属异常,而你的场景是外部认证服务不可达的业务异常,属于业务逻辑类异常,应该继承RuntimeException(非检查异常)来区分。
修改AuthServerException.java:
package com.nokia.sp.module.myVerify.portalapp.exception; public class AuthServerException extends RuntimeException { private static final long serialVersionUID = 1L; public AuthServerException(String message) { super(message); } }
2. 异常处理器作用范围问题
如果你的restTemplate.exchange调用代码是在Service层(而非当前LandingPageController的方法内),当前Controller的@ExceptionHandler只能处理本Controller方法抛出的异常,无法捕获Service层抛出的异常。此时需要改用全局异常处理器:
创建全局异常处理类:
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; import lombok.extern.slf4j.Slf4j; @ControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(AuthServerException.class) public ModelAndView handleAuthServerException(AuthServerException e) { log.info(e.getMessage()); ModelAndView mav = new ModelAndView(); mav.setViewName("auth-server-handler"); return mav; } }
@ControllerAdvice会让该处理器作用于所有Controller,无论异常是从Controller还是Service层抛出,只要未被提前捕获,都会被这里处理。
3. 优化try-catch逻辑
当前代码用catch (Exception e)捕获所有异常,范围过宽,且判断respNode == null的逻辑冗余:
当外部服务宕机时,restTemplate.exchange会直接抛出ResourceAccessException(连接超时/服务不可达),此时respNode必然为null,可精准捕获该异常:
ResponseEntity<AuthenticationResponse> respNode = null; try { respNode = restTemplate.exchange(url, HttpMethod.POST, httpEntity, new ParameterizedTypeReference<AuthenticationResponse>() {}); } catch (ResourceAccessException e) { log.info("Unable to reach: {} ", url); throw new AuthServerException("Auth Server Not Found"); }
4. 确保异常传播路径
如果restTemplate调用在LandingPageController的请求处理方法内,需确保该方法没有提前捕获AuthServerException,否则异常无法到达@ExceptionHandler。例如:
@GetMapping("/login") public String login() { // 调用包含restTemplate的逻辑,不捕获AuthServerException authenticate(); return "login"; } private void authenticate() { // 你的restTemplate调用代码,抛出AuthServerException }
总结
- 调整自定义异常继承类为
RuntimeException; - 若异常来自Service层,改用
@ControllerAdvice实现全局异常处理; - 缩小异常捕获范围,精准匹配服务不可达场景;
- 确保异常能正常传播到异常处理器。
内容的提问来源于stack exchange,提问作者Vansh

