CompletableFuture 总是抛出 500 内部服务器错误

时间:2021-06-19 08:15:38

标签: java spring multithreading spring-boot completable-future

我正在使用 Spring Boot 运行 Web 服务。下面的片段来自控制器。 我有一个自定义异常类(它扩展了 RuntimeException)。为了处理异常,我还有一个控制器建议。

当 someMethod() 抛出自定义异常时,我希望得到 400 - Bad Request。但是,可完成的未来限制了异常,我总是收到 500 - 内部服务器错误。

CompletableFuture.supplyAsync(() -> {
      return someMethod();
}
).whenCompleteAsync((response, throwable) -> {
  
});

控制器建议

@ControllerAdvice
public class CustomExceptionHandler extends Throwable {


@Order(Ordered.HIGHEST_PRECEDENCE)
@ExceptionHandler(value = CustomException.class)
public ResponseEntity<ErrorResponse> handleCustomException(
  CustomException ex) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setCode("400");
errorResponse.setDescription(ex.getMessage());
return new ResponseEntity<>(errorResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST);
 }


@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorResponse> handleGenericExceptions(Exception exception) {

ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setCode("500");
errorResponse.setDescription(exception.getMessage());
return new ResponseEntity<>(errorResponse, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
  }
 }

如果我在可完成的未来之外抛出自定义异常,我会得到预期的 400 - 错误请求。另一方面,如果我没有全局异常的处理程序,即使它在可完成的未来内被抛出,我也会收到 400 Bad Request。但是,两者都不能接受。我这样做是为了找到根本原因。

如何处理这种情况?

1 个答案:

答案 0 :(得分:-1)

当使用可完成的未来调用底层逻辑时,无论捕获的异常如何,所有异常都将被可完成的未来包装并作为 CompletionException 抛出。 因此,我们必须处理 CompletionException 并从全局处理程序返回适当的响应,或者当您调用某个方法时,在那里捕获异常本身,而不是重新抛出它,创建响应对象(带有错误代码和描述)你想发送和返回对象。