Java 如何将选中的异常从CompletableFuture传递给ControllerAdvice
如何使controllerAdvice类捕获从completablefutrue引发的异常。 在下面的代码中,我有一个方法Java 如何将选中的异常从CompletableFuture传递给ControllerAdvice,java,spring,java-8,completable-future,controller-advice,Java,Spring,Java 8,Completable Future,Controller Advice,如何使controllerAdvice类捕获从completablefutrue引发的异常。 在下面的代码中,我有一个方法checkId,它抛出一个选中的异常。我使用completablefuture调用此方法,并将选中的异常包装在CompletionException中。虽然我在控制器建议类中有一个处理程序方法,但它没有处理错误 package com.example.demo.controller; @RestController public class HomeController {
checkId
,它抛出一个选中的异常。我使用completablefuture调用此方法,并将选中的异常包装在CompletionException中。虽然我在控制器建议类中有一个处理程序方法,但它没有处理错误
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";
}
}
-
--
堆栈跟踪:
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]
@Deadpool和我能够确定问题所在 在completableFuture代码的catch块中,异常被包装在运行时异常的
CompletionException
exception中。当端点被命中时,在某个点上,CompletionException
异常被解包为原始异常,该异常类型为MyException
(选中的异常)。这意味着处理程序方法应该处理类型为MyException
的异常,而不是CompletionException
@ExceptionHandler(value = MyException.class)
@ResponseBody
public String handleCompletionException(MyException ex) {
return ex.getMessage();
}
你能用堆栈显示包的结构和错误信息吗trace@Deadpool. 添加了包结构。您可以添加主类以及带有堆栈跟踪@MoAAdded的错误消息吗@Deadpool@Deadpool. 你之前的评论起了作用。我还需要更改方法参数。以下是更改:
@ExceptionHandler(value=MyException.class)公共字符串handleCompletionException(MyException ex){return ex.getMessage();}
Wow,completablefuture打开异常。这就是它不起作用的原因!第一!
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]
@ExceptionHandler(value = MyException.class)
@ResponseBody
public String handleCompletionException(MyException ex) {
return ex.getMessage();
}