如何使controlleradvice类捕获从completablefutrue抛出的异常。在下面的代码中我有一个方法 checkId
抛出一个选中的异常。我使用completablefuture调用这个方法,并将选中的异常 Package 到completionexception中。虽然我在controller advice类中有一个handler方法,但它没有处理错误。
package com.example.demo.controller;
@RestController
public class HomeController {
@GetMapping(path = "/check")
public CompletableFuture<String> check(@RequestParam("id") int id) {
return CompletableFuture.supplyAsync(() -> {
try {
return checkId(id);
}
catch (Exception e) {
throw new CompletionException(e);
}
});
}
public String checkId(int id) throws Exception {
if (id < 0) {
throw new MyException("Id must be greater than 0");
}
return "id is good";
}
}
package com.example.demo;
public class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
package com.example.demo;
@ControllerAdvice
public class ExceptionResolver {
@ExceptionHandler(value = CompletionException.class)
public String handleCompletionException(CompletionException ex) {
return ex.getMessage();
}
}
--
package com.example.demo;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
堆栈跟踪:
com.example.demo.MyException: Id must be greater than 0
at com.example.demo.controller.HomeController.checkId(HomeController.java:30) ~[classes/:na]
at com.example.demo.controller.HomeController.lambda$0(HomeController.java:19) ~[classes/:na]
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692) ~[na:na]
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[na:na]
2020-01-24 14:38:30.489 ERROR 938 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.example.demo.MyException: Id must be greater than 0] with root cause
com.example.demo.MyException: Id must be greater than 0
at com.example.demo.controller.HomeController.checkId(HomeController.java:30) ~[classes/:na]
at com.example.demo.controller.HomeController.lambda$0(HomeController.java:19) ~[classes/:na]
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692) ~[na:na]
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177) ~[na:na]
1条答案
按热度按时间kzmpq1sx1#
@deadpool和我发现了问题所在。
在completablefuture代码的catch块中,异常被 Package 在
CompletionException
异常,它是运行时异常。当端点被击中时,在某个点CompletionException
异常被展开为类型为的原始异常MyException
(选中的异常)。这意味着handler方法应该处理类型为的异常MyException
而不是CompletionException
.