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

Micronaut 3.7.3中@Error注解失效问题求助

问题分析

你的全局异常处理器未触发,反而抛出io.micronaut.web.router.exceptions.UnsatisfiedRouteException: Required argument [HttpRequest request] not specified,核心原因是**@Error注解的方法参数不符合Micronaut的注入规则**,同时Vavr的Try.get()抛出的异常存在包装层级,导致处理器无法匹配目标异常。

解决方案

1. 调整异常处理器的参数顺序

Micronaut的@Error全局处理器要求异常对象作为第一个参数,HttpRequest等上下文参数需放在其后(或直接移除不需要的参数)。修改后的代码如下:

@Error(exception = ErrorContext, global = true)
HttpResponse<ErrorContext> onErrorContext(ErrorContext error, HttpRequest request) {
    HttpResponse.<ErrorContext>status(HttpStatus.valueOf(error.code)).body(error)
}

如果不需要HttpRequest,可直接简化为:

@Error(exception = ErrorContext, global = true)
HttpResponse<ErrorContext> onErrorContext(ErrorContext error) {
    HttpResponse.<ErrorContext>status(HttpStatus.valueOf(error.code)).body(error)
}

2. 解开Vavr Try抛出的异常包装

Try.get()在失败时会抛出CompletionException,你的自定义ErrorContext异常被包裹在该异常的cause中,导致Micronaut无法直接识别。需要在控制器中手动提取真实异常:

def show(Long id) {
    Try<AuthorResource> authorTry = authorService.get(id)
    authorTry.getOrElseThrow { throwable ->
        // 解开CompletionException的包装,抛出真实的自定义异常
        if (throwable instanceof CompletionException && throwable.cause instanceof ErrorContext) {
            throw (ErrorContext) throwable.cause
        }
        throw throwable
    }
}

3. 精准匹配子类异常

如果实际抛出的是ErrorContext的子类(如ErrorContextWithoutStacktrace),直接指定该子类作为@Error的exception参数,确保处理器精准匹配:

@Error(exception = ErrorContextWithoutStacktrace, global = true)
HttpResponse<ErrorContext> onErrorContext(ErrorContextWithoutStacktrace error) {
    HttpResponse.<ErrorContext>status(HttpStatus.valueOf(error.code)).body(error)
}
关键说明
  • Micronaut对@Error方法的参数顺序有严格要求,异常对象必须放在首位,否则会触发参数注入失败的异常。
  • Vavr的Try类抛出的异常会被CompletionException包装,必须手动提取内部真实异常,才能让全局处理器正确捕获并处理。

内容的提问来源于stack exchange,提问作者Luis Muñiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:30:44