Может ли CompleatableFuture выполняться исключительно в методе handle? - PullRequest
0 голосов
/ 28 апреля 2020

Я пытаюсь сопоставить исключение репозитория с исключением службы. Разве такой подход хорош?

@Override
public CompletableFuture<Void> delete(String id, Map<String, String> headers) {
  CompletableFuture<Void> future = repository.delete(id, headers);
  return future.handle((aVoid, throwable) -> {
    if (throwable != null) {
      Throwable cause = throwable.getCause();
      if (DbExcUtils.isFKViolation(throwable)) {
        future.completeExceptionally(new BadRequestException(HAS_ASSIGNED_RECORDS_MESSAGE));
      } else {
        future.completeExceptionally(cause);
      }
    }
    return aVoid;
  });
}

1 Ответ

1 голос
/ 28 апреля 2020

Метод handle будет вызывать его данные BiFunction только когда завершен целевой экземпляр CompletableFuture

Возвращает новый CompletionStage, когда этот этап завершается либо нормально, либо исключительно , выполняется с результатом и исключением этого этапа в качестве аргументов для предоставленной функции.

В этом смысле вы не можете завершить его снова. Javado c для completeExceptionally состояний

Если еще не завершено , вызывает вызовы get() и связанных методов, чтобы вызвать данное исключение .

Это, по сути, бездействие, когда будущее уже завершено.

Если вы просто хотите отобразить тип исключения, используйте exceptionally ,

Возвращает новый CompletionStage, который, когда этот этап завершается исключительно, выполняется с исключением этого этапа в качестве аргумента для предоставленной функции. В противном случае, если этот этап завершается нормально, возвращаемый этап также завершается нормально с тем же значением.

, которое, кажется, делает то, что вы пытались, ie. отобразить исключение, если оно было, или, в противном случае, вернуть результат.

Например,

return future.exceptionally(throwable -> {
    Throwable cause = throwable.getCause();
    if (DbExcUtils.isFKViolation(throwable)) {
        throw new CompletionException(new BadRequestException(HAS_ASSIGNED_RECORDS_MESSAGE));
    } else {
        throw new CompletionException(cause);
    }
});

Обратите внимание, что мы выкидываем новое исключение.

Кроме того, вы, вероятно, захотите проверить, является ли throwable значением CancellationException (без причины), и сбросить его, прежде чем приступить к работе с логиками сопоставления c.


* 1050. * Вы можете использовать obtrudeException, но я не рекомендую это

Принудительно заставляет последующие вызовы метода get() и связанных методов вызывать данное исключение, Завершено или нет уже . Этот метод предназначен для использования только в действиях по устранению ошибок, и даже в таких ситуациях может привести к продолжающимся зависимым завершениям с использованием установленных и перезаписанных результатов.

...