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
相关产品推荐
相关产品推荐

