Бросить оригинальное (внутреннее) исключение в функцию в CompletableFuture? - PullRequest
0 голосов
/ 11 октября 2018

Я новичок в Java, поэтому я надеюсь, что это не тривиально, но я действительно не могу найти то, что ищу.

У меня есть функция, которая выдает исключение:

public String foo(String s) throws MyException {
    if ("a".equals(s)){
      return s;
    } else {
      throw new MyException("Oh no!");
    }
}

Когда MyException просто:

class MyException extends Exception{

  String str1;

  MyException(String str2) {
    str1=str2;
  }
  public String toString(){
    return ("MyException Occurred: "+str1) ;
  }
}

Теперь у меня есть другой метод, который вызывает foo внутри CompletableFuture:

private CompletableFuture<String> test() throws Exception{
        return CompletableFuture.supplyAsync(() -> foo("b"));
}

Но foo выдает исключение, поэтому здесь возникает ошибка компиляции, так каквызов для foo - необработанное исключение.

Все, что я хочу, это выбросить оригинальное (внутреннее) исключение.Как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

У вас есть две проблемы.

  1. Вы не можете выбросить отмеченные исключения внутри лямбда-выражений, см., Например, этот ответ .Чтобы справиться с этим, вы можете либо использовать блок catch внутри лямбда-выражения, либо использовать исключение времени выполнения.

  2. supplyAsync(() -> foo("b")) означает, что он будет работать асинхронно в другом потоке в более поздний момент, например, когда выпозвоните .get() на результат.Поэтому для метода test() не имеет смысла генерировать исключение.

0 голосов
/ 11 октября 2018
  1. Метод foo не должен генерировать проверенное исключение, но необъявляемое исключение RuntimeException.

    class MyException extends RuntimeException
    
  2. Создание будущего уже не выполняетсяfoo сделает это при другом вызове.Так что не могу ничего бросить.

    private static CompletableFuture<String> test() {
        return CompletableFuture.supplyAsync(() -> foo("b"));
    }
    
  3. Завершение может ожидаться get() или get с таймаутом.Это передаст бросок MyException, обернув его как причину ExecutionException.

    try {test (). Get ();} catch (InterruptedException e) {e.printStackTrace ();} catch (ExecutionException e) {e.getCause (). printStackTrace ();}

  4. Не забывайте перехватывать исключение с exceptionally:

    try {
        String s = test().exceptionally(throwable -> {
           throwable.getCause().printStackTrace();
           return "xxx"; }).get();
        System.err.println("s=" + s);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    
0 голосов
/ 11 октября 2018

Вам необходимо обработать это проверенное исключение MyException внутри реализации CompletableFuture, потому что это «проверенное исключение», то есть оно получено из класса Exception.Либо обслужите его, либо измените MyException на расширение от RuntimeException, тогда вам не нужно обслужить его (перехватить).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...