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

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
}

总结

  1. 调整自定义异常继承类为RuntimeException;
  2. 若异常来自Service层,改用@ControllerAdvice实现全局异常处理;
  3. 缩小异常捕获范围,精准匹配服务不可达场景;
  4. 确保异常能正常传播到异常处理器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 20:16:06