
第一段引用上面的摘要:
本文旨在帮助开发者解决 Micronaut 框架中使用 @Error 注解进行全局异常处理时遇到的失效问题。通过分析常见原因,提供详细的排查步骤和解决方案,并提供示例代码,确保开发者能够正确配置和使用 @Error 注解,实现有效的全局异常处理。本文主要针对 Micronaut 3.7.3 及以上版本。
在使用 Micronaut 的 @Error 注解进行全局异常处理时,如果发现异常处理器没有被正确调用,通常有以下几个原因:
确保在异常处理方法中,导入的是 io.micronaut.http.HttpRequest:
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.annotation.Error;
import io.micronaut.http.annotation.Produces;
import javax.inject.Singleton;
@Produces // 添加 @Produces 注解
@Singleton
public class GlobalErrorHandler {
@Error(global = true)
public HttpResponse<?> handleException(HttpRequest request, Exception e) {
// 处理异常的逻辑
return HttpResponse.serverError("An unexpected error occurred.");
}
}@Error 注解的 exception 属性必须与实际抛出的异常类型精确匹配,或者指定异常的父类。如果你的 get() 方法抛出 ErrorContextWithoutStacktrace 异常,而 @Error 注解指定的是 ErrorContext,确保 ErrorContextWithoutStacktrace 是 ErrorContext 的子类。
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.annotation.Error;
import javax.inject.Singleton;
@Singleton
public class AuthorController {
// ... 其他代码 ...
@Error(exception = ErrorContext.class, global = true)
public HttpResponse<ErrorContext> onErrorContext(HttpRequest request, ErrorContext error) {
return HttpResponse.<ErrorContext>status(HttpStatus.valueOf(error.getCode())).body(error);
}
}如果希望处理所有 ErrorContext 及其子类的异常,可以指定 ErrorContext.class。
检查代码中是否有地方捕获了异常,导致 @Error 注解无法拦截。在你的 show() 方法中,虽然你捕获了异常并打印了堆栈信息,但是随后又重新抛出了异常,这应该是正确的。确保没有其他地方拦截了异常。
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Controller;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import io.vavr.control.Try;
@Controller("/author")
@Secured(SecurityRule.IS_ANONYMOUS)
public class AuthorController {
private final AuthorService authorService;
public AuthorController(AuthorService authorService) {
this.authorService = authorService;
}
@Get(uri = "/{id}")
@Secured("ROLE_VIEW")
HttpResponse<AuthorResource> show(Long id) {
try {
return HttpResponse.ok(authorService.get(id).get());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}如果在测试环境中使用 HttpClient 发起请求,并且期望 @Error 注解能够处理 HttpClientResponseException,需要使用 toBlocking().exchange() 方法,并捕获 HttpClientResponseException 异常。
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpMethod;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.http.client.exceptions.HttpClientResponseException;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import javax.inject.Inject;
@MicronautTest
public class AuthorControllerTest {
@Inject
@Client("/author")
HttpClient client;
@Test
void testGetNonExistingAuthor() {
Long badId = 546252431L;
HttpClientResponseException e = Assertions.assertThrows(HttpClientResponseException.class, () -> {
client.toBlocking().exchange(HttpRequest.create(HttpMethod.GET, "/" + badId));
});
Assertions.assertEquals(HttpStatus.NOT_FOUND, e.getStatus());
}
}建议使用全局异常处理器,确保所有未被controller捕获的异常都能被处理。
import io.micronaut.http.HttpRequest;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.annotation.Error;
import io.micronaut.http.annotation.Produces;
import javax.inject.Singleton;
@Produces // 添加 @Produces 注解
@Singleton
public class GlobalErrorHandler {
@Error(global = true)
public HttpResponse<?> handleException(HttpRequest request, Throwable e) {
// 处理异常的逻辑
e.printStackTrace(); // 打印堆栈信息,方便调试
return HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An unexpected error occurred: " + e.getMessage());
}
}注意: 需要添加@Produces注解,否则可能无法正确序列化响应体。
排查 Micronaut @Error 注解失效问题时,需要仔细检查 HttpRequest 的导入、异常类型的匹配、异常是否被正确抛出以及测试环境下的 HttpClientResponseException 处理。通过以上步骤,可以解决大多数 @Error 注解失效的问题,确保 Micronaut 应用能够正确处理异常,提供更健壮的服务。
以上就是Micronaut @Error 注解失效问题排查与解决的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号