首页 > 解决方案 > 在 CompletableFuture 运行异步时抛出异常的问题

问题描述

我正在开发一个微服务应用程序,在我想使用 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 块内抛出异常吗?

标签: spring-booterror-handlingmicroservicesjava-11completable-future

解决方案


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 /测试
你好世界


推荐阅读