5

Is there any way to throw an Exception while using a consumer in java 8?

For example:

    private void fooMethod(List<String> list) throws Exception {

    list.forEach(element->{
        if(element.equals("a")) {
            throw new Exception("error!");
        }
    });

}

This gives me a compiler error saying: Unhandled exception type Exception

What is the correct way to throw an exception in this case?

Naman
  • 27,789
  • 26
  • 218
  • 353
OEH
  • 665
  • 11
  • 29
  • `if(list.contains("a")) throw new Exception("error!");` – Holger Mar 10 '20 at 14:57
  • 1
    Looks to me like someone already asked this question a few years ago. [Java 8 Lambda function that throws exception?](https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception). Did you not Google for _java lambda throw exception_ before posting your question? Have you not read [How much research effort is expected of Stack Overflow users?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users) – Abra Mar 10 '20 at 16:03

3 Answers3

5

Since Exception and its subclass (other than RuntimeException) are checked Exception and in lambda, you can't throw checked exception. Hence you should use RuntimeException:

private void fooMethod(List<String> list) throws Exception {
    list.forEach(element->{
        if(element.equals("a")) {
            throw new RuntimException("error!");
        }
    });
}
Nitin Bisht
  • 5,053
  • 4
  • 14
  • 26
Sourav Jha
  • 411
  • 2
  • 11
3

Streams and related classes are not designed to use checked exceptions. But any RuntimeException can be thrown at any point in code, thus the trick is to throw a runtime whose cause (exception chaining) is the appropriate checked exception :

private void fooMethod(List<String> list) throws Exception {   
    list.forEach(element->{
        if(element.equals("a")) {
            throw new Runtime(new Exception("error!"));
        }
    });  
}

Then in the catching code you just have to get the original checked exception encapsulated :

try {
    fooMethod(someList);
} catch(Throwable e) {
    Exception ex = e.getCause();
}
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
3

You can do it with apache commons-lang3 library.

https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/function/Failable.html

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

You can write:

import org.apache.commons.lang3.function.Failable;

private void fooMethod(List<String> list) throws Exception {
    list.forEach(Failable.asConsumer(element->{
        if(element.equals("a")) {
            throw new Exception("error!");
        }
    }));
}
E.H.
  • 326
  • 1
  • 7