How to handle exception in Java 8 Stream?

I have a method where I loop through a list and create a List. When doing this, I call the (createResult) method to give the result, it also throws a CustomException, which I wrap as a ResultClassException. But I keep getting Unhandled Exception error.

My code:

 private  List<Result> getResultList(List<String> results) throws ResultClassException {
    List<Result> resultList = new ArrayList<>();
        results.forEach(
                (resultName) -> {
                    if (!resultRepository.contains(resultName)) {
                       try {
                           final Result result = createResult(resultName);
                           resultList.add(result);
                       } catch (CustomException e) {
                           throw new ResultClassException("Error",e);
                       }

                    } else {
                        resultList.add(resultRepository.get(resultName));
                        log.info("Result {} already exists.", resultName);
                    }
                }
        );
        return  Collections.unmodifiableList(resultList);
    }

      

Can someone tell me what I am doing wrong?

+3


source to share


4 answers


You probably have too many responsibilities in your method. You should consider splitting it into a method that only displays and another that collects them.



private List<Result> getResultList(List<String> names) throws ResultClassException {
  try {
    return names.stream()
        .map(this::getOrCreateResult)
        .collect(collectingAndThen(toList(), Collections::unmodifiableList));
  } catch (RuntimeException e) {
    if (e.getCause() instanceof CustomException) {
      throw new ResultClassException("Error", e.getCause());
    }
    throw e;
    // Or use Guava propagate
  }
}

private Result getOrCreateResult(String name) {
  if (!resultRepository.contains(name)) {
    try {
      return createResult(name);
    } catch (CustomException e) {
      throw new RuntimeException(e);
    }
  } else {
    log.info("Result {} already exists.", name);
    return resultRepository.get(name);
  }
}

      

+5


source


I would not suggest using RuntimeException as that would lead you into bad coding practice. Try to handle the ResultClassException in the calling getResultList (...) method.



+1


source


You cannot handle checked exception from within threads

One way would be throwing RuntimeException

out createResult

or writing a wrapping method createResult

that will catch and handle the checked exception.

0


source


With lambda expressions in Java 8, you represent inner classes. This way the exception will be thrown inside your anonymous inner class. try adding this when you add your throw new ResultClassException ("Error", e);

                       Thread.getAllStackTraces()
                          .keySet()
                          .stream()
                          .map(Thread::getStackTrace)
                          .map(Arrays::asList)
                          .forEach(list -> System.out.println(list.stream()
                                                                  .map(i -> i.toString())
                                                                  .collect(Collectors.joining("\n\t"))));

      

and watch the thread that calls it. You will see that your exception is out of scope that you would expect from a lambda. You will see that the thread creates many threads and your exception is not part of the thread you want. You can wrap your method like this: Java 8: How can I work with exception metadata methods in streams?

0


source







All Articles