【问题标题】:Problem throwing exceptions inside CompletableFuture run async在 CompletableFuture 运行异步时抛出异常的问题
【发布时间】:2021-10-04 14:30:55
【问题描述】:

我正在开发一个微服务应用程序,在服务布局中我想使用 CompletableFuture.runAsync() 调用。问题是当我想抛出异常时,我有自己的处理程序异常,但是当它在 CompletedFuture 内的 catch 块中产生时,我无法捕获错误,如下所示:

控制器:

@PostMapping(path="/offers/offer")
    public CompletableFuture<Oferta> infoPropiedad(@Valid @RequestBody OfertaRequest inDTO) throws 
    WebServiceBadResponseException, SOAPException, IOException, InterruptedException, ExecutionException  {
        System.out.println("THREAD: "+Thread.currentThread().getName());
        CompletableFuture<Oferta> outTO = new CompletableFuture<Oferta>();
        
        return CompletableFuture.supplyAsync(()->{
            try {
                return ofertasService.ofertasService(inDTO);
            } catch (Exception e) {
                System.out.println("Error inesperado en la capa del controlador");
            }
            return null;
        });
    }

服务:

CompletableFuture<OfertaCrm> completableFutureCRM = 
                CompletableFuture.supplyAsync(()->  {
                    try {
                        return clientOferta.llamadaWebServiceOfertas(inDTOCrm);
                    } catch (Exception e1) {
                        //throw Exception and capture it with my handler class
                    }
                });

客户端:

    public OfertaCrm llamadaWebServiceOfertas(OfertaRequestCRM inDtoCrm) 
            throws SOAPException, IOException {

                CompletableFuture<OfertaCrm> completableFuture = new CompletableFuture<OfertaCrm>();
                
                logger.info("Iniciamos la llamada al WS");
//Error produces here and I want to controle it and capture with my handler class

错误处理程序:

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({
        WebServiceBadResponseException.class,
        SOAPException.class,
        IOException.class
    })
    @ResponseBody
    public ErrorMessage internalError(Exception exception) {
        return new ErrorMessage(exception,exception.getMessage());
    }

我无法应用正确的表格。知道如何在 supplyAsync 块内抛出异常吗?

【问题讨论】:

  • 也许this answer 有帮助……
  • 谢谢但不是我要搜索的,当异常抛出我的处理程序时我需要控制这个异常并从我的端点返回一个正文响应,我不知道我是否不明白可完成的未来功能,但我需要在我当前的代码中回答。感谢您尝试帮助我:)

标签: spring-boot error-handling microservices java-11 completable-future


【解决方案1】:

CompletableFuture 会将执行过程中抛出的异常包装在 CompletionException 中。您可以通过直接拦截根本原因异常来处理它。下面是一个简化的例子。

控制器:

@RestController
public class SimpleController {
    @Autowired
    SimpleService simpleService;

    @GetMapping("/testing")
    public CompletableFuture<Integer> testing(){
        return simpleService.doStuff();
    }
}

服务:

@Service
public class SimpleService {

    public CompletableFuture<Integer> doStuff(){
        // 1 / 0 will throw ArithmeticException
        return CompletableFuture.supplyAsync(() -> 1 / 0);
    }
}

控制器建议:

@RestControllerAdvice
public class SimpleControllerAdvice {

    @ExceptionHandler(ArithmeticException.class)
    public String handleCompletionException(ArithmeticException ex){
        return "hello world";
    }
}

GET /测试
你好世界

【讨论】:

  • 你为什么用supplyAsync而不是completedFuture
  • 对于 supplyAsync,1 / 0 将在单独的线程上处理。
  • 但是如果它没有用@Async注解标记呢?
  • 默认情况下会使用 ForkJoinPool.commonPool 除非你传入自己的自定义执行器
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
相关资源
最近更新 更多