Исключение исключения из лямбда

Учитывая этот код java 8

public Server send(String message) {
    sessions.parallelStream()
        .map(Session::getBasicRemote)
        .forEach(basic -> {
          try {
            basic.sendText(message);
          } catch (IOException e) {
            e.printStackTrace();
          }
        });

    return this;
}

как нам сделать это IOException делегировать стек вызова метода? (вкратце, как сделать этот метод броском этого IOException?)

Lambdas в java не очень дружелюбен к обработке ошибок...

Ответы

Ответ 1

Мой подход заключается в том, чтобы скрытно выбросить его из лямбда, но позаботьтесь о том, чтобы метод send объявлял его в своем предложении throws. Используя Exceptional класс я разместил здесь:

public Server send(String message) throws IOException {
  sessions.parallelStream()
          .map(Session::getBasicRemote)
          .forEach(basic -> Exceptional.from(() -> basic.sendText(message)).get());
  return this;
}

Таким образом, вы фактически делаете компилятор "отвлекшись" всего лишь немного, отключив его проверку исключений в одном месте вашего кода, но, объявив исключение в вашем методе send, вы восстанавливаете регулярное поведение для все его вызывающие.

Ответ 2

I написал расширение в Stream API, который позволяет исключать проверенные исключения.

public Server send(String message) throws IOException {
    ThrowingStream.of(sessions, IOException.class)
        .parallelStream()
        .map(Session::getBasicRemote)
        .forEach(basic -> basic.sendText(message));

    return this;
}

Ответ 3

Проблема в том, что все @FunctionalInterface, используемые в lambdas, не позволяют исключать исключения, за исключением исключенных исключений.

Одно из решений использует мой пакет; с ним, ваш код может читать:

sessions.parallelStream()
    .map(Session::getBasicRemote)
    .forEach(Throwing.consumer(basic -> basic.sendText(message)));
return this;