Skip to content
Advertisement

Exception handling with Consumer functions in Java 8

This code gives me a compile error on the line processBatch(batch, this::backupMetacard); The process batch method wraps the consumer in a try/catch block, but Java will not compile the call.

private synchronized void drain() {

    for (List<Metacard> batch : Lists.partition(metacards, BATCH_SIZE)) {
        getExecutor().submit(() -> {

            processBatch(batch, this::backupMetacard);
        });
    }
    metacards.clear();
}

void processBatch(List<Metacard> metacards, Consumer<Metacard> operation) {

    List<String> errors = new ArrayList<>();
    for (Metacard metacard : metacards) {
        try {
            operation.accept(metacard);
        } catch (IOException e) {
            errors.add(metacard.getId());
        }
    }

    if (!errors.isEmpty()) {
        LOGGER.info("Plugin processing failed. This is allowable. Skipping to next plugin.",
                pluginExceptionWith(errors));
    }
}

private void backupMetacard(Metacard metacard) throws IOException {...}

Advertisement

Answer

The problem is that in the following snippet, the method backupMetacard declares to throw the checked IOException.

getExecutor().submit(() -> {
    processBatch(batch, this::backupMetacard);
                        ^^^^^^^^^^^^^^^^^^^^ // <-- this throws a checked exception
});

As such, it does not comply anymore with the contract of the functional method of Consumer, which is apply and doesn’t declare to throw checked exceptions.

Wrap this into a try-catch, where you can throw an unchecked exception instead UncheckedIOException:

getExecutor().submit(() -> {
    processBatch(batch, metacard -> {
        try {
            backupMetacard(metacard);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    });
});
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement