@ControllerAdvice无法精准匹配NotLoginException异常的解决方案
问题现象
运行代码时抛出异常:java.lang.RuntimeException: cn.dev33.satoken.exception.NotLoginException: Invalid Token:ldxutBDDKBEDa9LjWNTKLFbW7g7B86qU,异常触发后进入了handleRuntimeException处理方法,没有走到预期的returnNotLoginException处理逻辑。
异常抛出位置在自定义锁键生成类的buildKey方法中,调用StpUtil.getLoginId()时触发未登录异常。
关联代码
自定义锁键生成类
@Component @Slf4j @Primary public class MyLockKeyBuilder extends DefaultLockKeyBuilder { @Override public String buildKey(MethodInvocation invocation, String[] definitionKeys) { String key = super.buildKey(invocation, definitionKeys); Object loginId = StpUtil.getLoginId(); // 此处抛出NotLoginException key = loginId.toString(); return key; } }
全局异常处理器
@ControllerAdvice(basePackages = "com.test") @Slf4j public class GraceExceptionHandlerApp { @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(value = NotLoginException.class) @ResponseBody public JSONObject returnNotLoginException(NotLoginException e) { e.printStackTrace(); String message = e.getMessage(); ResponseStatusEnum failed = ResponseStatusEnum.UNAUTHORIZED; failed.setMsg(message); return ZheliResult.exception(failed); } @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ExceptionHandler(RuntimeException.class) @ResponseBody public JSONObject handleRuntimeException(RuntimeException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); return ZheliResult.errorCustom(ResponseStatusEnum.FAILED); } // 其余异常处理逻辑省略 }
核心诉求
调整异常处理逻辑,让NotLoginException能够路由到returnNotLoginException方法完成处理。
问题补充背景
- 系统为分布式架构,服务间通过RPC通信,
MyLockKeyBuilder部署在服务提供方,GraceExceptionHandlerApp部署在服务消费方。 - 服务提供方抛出的异常传递到消费方前,会经过
ExceptionFilter过滤器处理,为避免跨服务序列化异常,消费方无法识别的异常类型会被统一包装为RuntimeException后再传递。
最终解决方案
重写ExceptionFilter类的异常处理逻辑,将NotLoginException加入可透传的异常白名单,放行原始异常实例使其直接传递到消费方,即可被消费方的全局异常处理器精准匹配,路由到预期的未登录异常处理方法。
内容的提问来源于stack exchange,提问作者Criwran
相关产品推荐
相关产品推荐

