How to iterate a stream even if exceptions are thrown?

java stream throw exception if more than one
java 8 stream throw exception if empty
java stream exception
java 8 stream propagate exception
stream filter throws exception
java 8 map get or throw exception
java optional catch (exception)
exception handling stream map
stream.map(obj -> doMap(obj)).collect(Collectors.toList());

private String doMap(Object obj) {
    if (objectIsInvalid) {
    throw new ParseException("Object could not be parsed");
    }
}

Problem: how can I throw the exception and make the stream iteration know that it should not break the whole iteration, but continue with the next element (and eventually log failed objects)?

Without an exception you can work with Optionals:

stream.map(obj -> doMap(obj))
      .filter(obj -> obj.isPresent())
      .collect(Collectors.toList());

private Optional<String> doMap(Object obj) {
   if (objectIsInvalid) {
    return Optional.empty();
   }
}

Exception Handling in Java Streams, We take a look at exception handling in Java Streams, focusing on wrapping it into When you want to use a method that throws a checkedException, you have to forEach(System.out::println); There may be various validation related exceptions invoked even before the actual controller code is invoked. Developers moving to Java 8 adopt the new approach pretty easily, and the resulting code tends to be shorter and easier to follow, unless you have to deal with exceptions. Here you’ll see three primary ways to handle exceptions in a stream pipeline and each approach will include several examples. Unchecked Exceptions

Here's one weird trick you can use to improve your exception handling.

Let's say your mapper function is like this:

String doMap(Object obj) {
    if (isInvalid(obj)) {
        throw new IllegalArgumentException("info about obj");
    } else {
        return obj.toString();
    }
}

This returns a result if the object is valid, but it throws an exception if the object is invalid. Unfortunately if you stick this directly into a pipeline, any error will stop the pipeline execution. What you want is something like an "either" type that can hold either a value or an error indicator (which would be a exception in Java).

Turns out that CompletableFuture can hold either a value or an exception. Although it's intended for asynchronous processing -- which isn't occurring here -- we only have to contort it a little bit to use for our purposes.

First, given a stream of objects to process, we call the mapping function wrapped in a call to supplyAsync:

 CompletableFuture<String>[] cfArray = 
        stream.map(obj -> CompletableFuture.supplyAsync(() -> doMap(obj), Runnable::run))
              .toArray(n -> (CompletableFuture<String>[])new CompletableFuture<?>[n]);

(Unfortunately, the generic array creation gives an unchecked warning, which will have to be suppressed.)

The odd construct

 CompletableFuture.supplyAsync(supplier, Runnable::run)

runs the supplier "asynchronously" on the provided Executor Runnable::run, which simply runs the task immediately in this thread. In other words, it runs the supplier synchronously.

The trick is that the CompletableFuture instance returned from this call contains either the value from the supplier, if it returned normally, or it contains an exception, if the supplier threw one. (I'm disregarding cancellation here.) We then gather the CompletableFuture instances into an array. Why an array? It's setup for the next part:

CompletableFuture.allOf(cfArray).join();

This normally waits for the array of CFs to complete. Since they've been run synchronously, they should already all be complete. What's important for this case is that join() will throw a CompletionException if any of the CFs in the array has completed exceptionally. If the join completes normally, we can simply gather up the return values. If the join throws an exception, we can either propagate it, or we can catch it and process the exceptions stored in the CFs in the array. For example,

try {
    CompletableFuture.allOf(cfArray).join();
    // no errors
    return Arrays.stream(cfArray)
                 .map(CompletableFuture::join)
                 .collect(toList());
} catch (CompletionException ce) {
    long errcount =
        Arrays.stream(cfArray)
              .filter(CompletableFuture::isCompletedExceptionally)
              .count();
    System.out.println("errcount = " + errcount);
    return Collections.emptyList();
}

If all are successful, this returns a list of the values. If there are any exceptions, this counts the number of exceptions and returns an empty list. Of course, you could easily do something else, like log the details of the exceptions, filter out the exceptions and return a list of valid values, etc.

Handling checked exceptions in Java streams – O'Reilly, Rather than iterate over a collection of values, we transform streams using a pipeline. What would you do if you did want to deal with the thrown exception? It looks familiar, is easy to understand, and (even better) you can  That's because the sc.nextInt doesn't actually get the f off the input stream, it just throws the exception leaving the f still to be read by the next call to sc.next. You could try using sc.next to read in the number into a String and then use Integer.parseInt to convert the String to a number.

If you want a means to quietly ignore those elements that throw an exception when mapped, you can define a helper method that either returns a success or nothing, as a stream of 0 or 1 elements, and then flatMap your stream with that method.

import static java.util.stream.Collectors.toList;

import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class Fish {
    private int weight;
    public Fish(int weight) { this.weight = weight; }
    public String size() {
        if (weight < 10) {
            return "small";
        } else if (weight < 50) {
            return "medium";
        } else if (weight < 100) {
            return "large";
        } else {
            throw new RuntimeException("I don't believe you");
        }   
    }

    public static <T> Stream<T> successOrNothing(Supplier<T> supplier) {
      try {
        return Stream.of(supplier.get());
      } catch (Exception e) {
        return Stream.empty();
      }
    }

    public static void main(String[] args) {
        Stream<Fish> fishes = Stream.of(new Fish(1000), new Fish(2));
        List<String> sizes = fishes
          .flatMap(fish -> successOrNothing(fish::size))
          .collect(toList());
        System.out.println(sizes);
    }
}

Each element in the stream gets mapped to 1 element (if the call returned successfully) or 0 (if it did not). This might be easier or more straightforward then the "change the method to return null or Optional.empty() instead of throwing" pattern, especially when dealing with a method whose contract already is defined and you don't want to change.

Caveat: this solution is still silently ignoring exceptions; that is inappropriate in many situations.

Repackaging Exceptions In Streams, How to repackage checked exceptions that get thrown in a Java stream pipeline so that they can Java 8 is a couple of years old but there are still use cases, not even edge cases, that the (If you're not down with having streams as parameters or return values, assume the forEach(System.out::println);. The use of break keyword is discouraged Here is a very simple implementation to break away after implementing a retry mechanism This iterates over the loop for the specified number of times and also if the exception still persists, then the exception is thrown.

I would do following...

stream.map(doMapLenient())
      .filter(Objects::nonNull)
      .collect(Collectors.toList());

private String doMap(Object obj) {
    if (objectIsInvalid(obj)) {
    throw new ParseException("Object could not be parsed");
    }
    return "Streams are cool";
}

private Function<Object, String> doMapLenient() {
  return obj -> {
     try {
       return doMap(obj);   
   } catch (ParseExcepion ex) {
       return null; 
   }
}

here you can add nicely also some logging in catch part

Java 8: Lambda-Streams, Filter by Method with Exception, But even if I explicitly use a try-catch-Block like below, it still doesn't compile because I don't catch the Exception. So either there is a bug in JDK,  You can throw exceptions in lambdas. A lambda is allowed to throw the same exceptions as the functional interface implemented by the lambda. If the method of the functional interface doesn't have a throws clause, the lambda can't throw CheckedExceptions. (You still can throw RuntimeExceptions).

You can just explicitly iterate over the stream elements using an iterator:

Stream<Object> stream = ... // throws unchecked exceptions;
Iterator<Object> iterator = stream.iterator();
while (iterator.hasNext()) {
    try {
        Object obj = it.next();
        // process
    } catch (ParseException ex) {
        // handle
    }
}

Workaround for Java checked exceptions, If you are calling a method which literally can never throw the exception that it bubble and probably be catched in the main program loop by some "catch Exception" or /27644361/how-can-i-throw-checked-exceptions-from-inside-​java-8-streams Even though I curate the Paguro library above, I'm converting all the Java  Code in a finally clause is almost always executed even when exceptions are thrown. Handle common conditions without throwing exceptions For conditions that are likely to occur but might trigger an exception, consider handling them in a way that will avoid the exception.

State of the Collections, This version describes "Iteration 3" of the API design; for comparison, see Iteration 1. As the Java language acquires lambda expressions as part of JSR 335, this has side effect of making our Collections interfaces look even more out of date! stream rather than a new collection (which might just get thrown away by the  MSDN using documentation also confirms this answer: The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler. – broadband May 22 '14 at 8:00

Java 8 Stream API: Part 1 | Pluralsight, As of 2013, over 3 billion devices used Java, with the language being used primarily in web Some even say it is an outdated language. They must not throw more exceptions than specified in the throws clause of the functional interface method. Returns an iterator for the elements of the stream. The first form (1) returns the current exception mask for the stream. The second form (2) sets a new exception mask for the stream and clears the stream's error state flags (as if member clear () was called).

Error Handling in Streams • Akka Documentation, The below stream fails with ArithmeticException when the element 0 goes Throwing an exception inside recover will be logged on ERROR level automatically. toMat(Sink.foreach(event => println(s"Got event: $event")))(Keep​.left) .run()  A story of Checked Exceptions and Java 8 Lambda Expressions javadevguy Uncategorized February 22, 2016 9 Minutes Image you are writing a small, awesome Transaction Management library to be used in a project you are working on.

Comments
  • If you don't want to return anything when an exception is thrown, perhaps you should use flatmap instead of map.
  • Maybe you can just return null instead of a String and filter on non-null objects?
  • I create the exception myself. But it does not matter, it may likewise be throws of any other framework class I use in the map method.
  • @Davio yes for continuing the loop that's a great idea to return null instead of throwing an exception and filter accordingly after the mapping. With the current limitations of streams probably the best solution, you might want to add this as an answer.
  • Reopened; not a duplicate of stackoverflow.com/questions/27644361/… . That question has to do with the inability to throw checked exceptions from lambdas matching predefined functional interfaces. This question is about how to deal with exceptions (checked or unchecked) without stopping stream processing.
  • I guess it depends on what you're doing, but silently suppressing exceptions is usually a very bad idea. If someone passed in invalid data, or if the user specified invalid input, you should tell them about it, not behave as if everything is fine.
  • I don’t know why you want to "work with nulls and Optionals". Normally you should decide for either, using null or using Optional. Your code returns null in doMap and tries to invoke .isPresent() on it within filter(…)
  • Please don't do this. If something is invalid, you probably want to return an empty Optional instead of null. As it stands, you will get NPE when isPresent is called on null.
  • @StuartMarks Yes, I fixed it.
  • Sometimes this solution is not possible, when you use external service which simply throws exception.
  • Neat solution! Do you think this trick would impact performance?