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

Quarkus中Exception Mapper无法触发调用的问题求助

Quarkus自定义Exception Mapper未触发的排查与解决

一、检查自定义异常类型

确保AuthConsentException是RuntimeException子类,或者在LoginResource的POST方法上显式声明throws AuthConsentException。JAX-RS仅自动处理未声明的RuntimeException,Checked Exception必须在方法签名中抛出才会被映射器捕获。
示例:

// 正确的自定义异常定义
public class AuthConsentException extends RuntimeException {
    public AuthConsentException(String message) {
        super(message);
    }
}

二、验证@ServerExceptionMapper实现的正确性

如果用类内映射方法,确保注解指定了正确的异常类型,且方法返回Response、权限为public:

@Path("/login")
public class LoginResource {

    @POST
    public Response login(LoginRequest request) {
        throw new AuthConsentException("需要用户授权");
    }

    @ServerExceptionMapper(AuthConsentException.class)
    public Response handleAuthConsentException(AuthConsentException e) {
        return Response.status(Response.Status.FORBIDDEN)
                .entity(Map.of("error", e.getMessage()))
                .build();
    }
}

三、独立Provider类的扫描与优先级配置

如果用独立的AuthConsentExceptionMapper,需满足:

  • 类上同时标注@Provider和@Priority(确保优先级高于默认映射器)
  • 类所在包被Quarkus组件扫描覆盖(默认扫描当前包及子包,若在其他包需在application.properties中配置quarkus.jaxrs.scan-packages)
    示例:
@Provider
@Priority(Priorities.USER)
public class AuthConsentExceptionMapper implements ExceptionMapper<AuthConsentException> {
    @Override
    public Response toResponse(AuthConsentException e) {
        return Response.status(Response.Status.FORBIDDEN)
                .entity(Map.of("code", "AUTH_CONSENT_REQUIRED", "message", e.getMessage()))
                .build();
    }
}

四、清理开发模式缓存

如果在quarkus dev模式下测试,可能存在类加载缓存问题:

  • 停止服务后删除target/目录再重启
  • 或直接用quarkus dev --clean启动,强制清理缓存

五、排查全局异常拦截冲突

若项目存在其他ExceptionMapper<Throwable>或全局拦截器,可能优先捕获异常。可通过调整@Priority值(数值越小优先级越高)确保你的映射器先执行。

六、验证映射方法是否被调用

在映射方法中添加日志,确认是否触发:

@ServerExceptionMapper(AuthConsentException.class)
public Response handleAuthConsentException(AuthConsentException e) {
    System.out.println("AuthConsentException已被捕获"); // 测试日志
    return Response.status(Response.Status.FORBIDDEN)
            .entity(Map.of("error", e.getMessage()))
            .build();
}

若日志未打印,说明映射器未被触发;若打印但响应异常,再排查Response处理逻辑。


内容的提问来源于stack exchange,提问作者Денис Анд

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:50:05