1

I have encountered and contributed to projects which use Java8 streams and lambdas extensively. The code is littered with blocks like this:

... some other code ... -> {
  try {
    ... some more code ...
  }
  catch(SomeException e) {
    throw new RuntimeException(e);
  }
} ... 

or alternatively

private void someMethodWhichWillBeCalledInALambda(...) {
  try {
    ... some code ...
  }
  catch(SomeException e) {
    throw new RuntimeException(e);
  }
}

In addition to littering the code with these extra try/catch blocks, we also lose the ability to do proper exception handling up the stack (in the callers of the code that uses lambdas).

Lambdas break the long-standing Java best practice of propagating exceptions up the stack to the nearest block of code capable of handling it meaningfully. I cannot quote an authoritative source for this best practice at the moment, perhaps someone can point to it in the comments. In these examples, the code in the lambda is too low-level to meaningfully handle the exception.

My question is, what is the alternative to this mess?

In keeping with SO rules, please limit your answers only to working code, although I wouldn't mind in the comments some bigger ideas... such as possible enhancements to the Java language and how to get a proposal sent through the JCP, if one doesn't already exist.

Alex R
  • 11,364
  • 15
  • 100
  • 180
  • You have to catch the exception because most of the really useful Java8 stream methods such as map(), filter(), etc, do not take an exception-throwing (propagating) lambda. – Alex R Mar 24 '18 at 19:35
  • A library such as [Vavr](http://www.vavr.io/) gives you checked exception lambdas - this of course doesn't solve every problem. For example something like [this](http://www.baeldung.com/exceptions-using-vavr). Still somewhat ugly... – Boris the Spider Mar 24 '18 at 19:37
  • Possible duplicate of [How can I throw CHECKED exceptions from inside Java 8 streams?](https://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams) – Sean Van Gorder Mar 26 '18 at 19:44

1 Answers1

0

I know this is kind of and old issue, but Im currently solving it this way. I dont know if it is the BEST OF THE approaches, but it works for me

final Set<MyException> exceptionHolder = ConcurrentHashMap.newKeySet();

    List<fooType> foos = something.stream().parallel().map(someStuff -> {
    try{     
          return foo();
    } catch (MyException e) {
          exceptionHolder.add(e);
          return null;
    }

    }).collect(Collectors.toList());

if (exceptionHolder.isEmpty()) {
          return foos;
} else {
          throw exceptionHolder.stream().findFirst().get();
}
gdoghel
  • 21
  • 3