Skip to content

robtimus/throwing-functions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

throwing-functions

Maven Central Build Status Quality Gate Status Coverage Known Vulnerabilities

The throwing-functions library provides copies of the functional interfaces in java.util.functions that allow their functional interface methods to throw checked exceptions.

Each of these interfaces also contains static methods unchecked and checked to convert them to and from their matching equivalents in java.util.functions. For example, to delete all files in a directory that match a filter, you can use ThrowingConsumer.unchecked:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
    stream.forEach(ThrowingConsumer.unchecked(Files::delete));
} catch (UncheckedException e) {
    e.throwCauseAs(IOException.class);
}

The throwCauseAs method above is declared to return any type, allowing it to be used as return statement. For instance, using ThrowingToLongFunction.unchecked:

static long getTotalSize(Path dir) throws IOException {
    try (Stream<Path> stream = Files.walk(dir)) {
        return stream
                .filter(Files::isRegularFile)
                .mapToLong(ThrowingToLongFunction.unchecked(Files::size))
                .reduce(0, Long::sum);
    } catch (UncheckedException e) {
        return e.throwCauseAs(IOException.class);
    }
}

Handling checked exceptions

Each interface has a set of default methods that allow any thrown checked exception to be handled. These come in the following variants:

  • onErrorThrowAsChecked and onErrorThrowAsUnchecked transform the caught checked exception into another exception.
  • onErrorHandleChecked and onErrorHandleUnchecked invoke a function or action on the caught checked exception.
  • onError<Operation>Checked and onError<Operation>Unchecked discard the caught checked exception and invoke an instance of the same interface or its unchecked variant.
  • onErrorGetChecked and onErrorGetUnchecked discard the caught checked exception and return the result of a supplier (only for interfaces that don't return void).
  • onErrorReturn discards the caught checked exception and returns a fixed value (only for interfaces that don't return void).
  • onErrorDiscard discards the caught checked exception without doing anything else (only for interfaces that return void).
  • unchecked wraps the caught checked exception in an instance of UncheckedException. This is similar to calling the static unchecked method with the instance as argument.

The variants ending with Checked return an instance of the same interface but with a possibly different checked exception that can be thrown. The variants ending with Unchecked return an instance of the matching unchecked variant.

Using these methods, the above example can be changed to throw an UncheckedIOException instead:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
    stream.forEach(ThrowingConsumer.of(Files::delete).onErrorThrowAsUnchecked(UncheckedIOException::new));
} catch (UncheckedIOException e) {
    throw e.getCause();
}

It also becomes easy to log exceptions instead of letting them be relayed to the caller:

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
    stream.forEach(ThrowingConsumer.of(Files::delete).onErrorHandleUnchecked(e -> logger.info("Failed to delete a file", e)));
}

And the getTotalSize method shown above can be changed to not fail if a file's size cannot be determined:

static long getTotalSize(Path dir) throws IOException {
    try (Stream<Path> stream = Files.walk(dir)) {
        return stream
                .filter(Files::isRegularFile)
                .mapToLong(ThrowingToLongFunction.of(Files::size).onErrorReturn(0))
                .reduce(0, Long::sum);
    }
}

Handling unchecked exceptions

Like the functional interfaces in java.util.functions, any thrown instance of Error, RuntimeException or one of their sub classes is relayed to the caller.

About

A collection of functional interfaces that can throw checked exceptions

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages