Given the utility class Completions(listed below), users can easily throw checked exceptions:
public CompletionStage<String> readLine()
{
return Completions.supplyAsync(() ->
{
try (BufferedReader br = new BufferedReader(new FileReader("test.txt")))
{
return br.readLine();
}
});
}
Any exceptions thrown by a lambda (checked or not) will be wrapped in CompletionException, which is consistent with the behavior CompletableFuturefor excluded exceptions.
Things get a little ugly for intermediate steps like thenApply(), but this is not the end of the world:
public CompletionStage<String> transformLine()
{
return readLine().thenApply(line ->
Completions.wrapExceptions(() ->
{
if (line.contains("%"))
throw new IOException("Lines may not contain '%': " + line);
return "transformed: " + line;
}));
}
Here are some methods from the utility class Completions. You can wrap other methods CompletableFuturethis way.
public final class Completions
{
public static <T> CompletionStage<T> supplyAsync(Callable<T> callable, Executor executor)
{
return CompletableFuture.supplyAsync(() -> wrapExceptions(callable), executor);
}
public static <T> T wrapExceptions(Callable<T> callable)
{
try
{
return callable.call();
}
catch (CompletionException e)
{
throw e;
}
catch (ExecutionException e)
{
throw new CompletionException(e.getCause());
}
catch (Throwable e)
{
throw new CompletionException(e);
}
}
public static <T> CompletionStage<T> supplyAsync(Callable<T> callable)
{
return CompletableFuture.supplyAsync(() -> wrapExceptions(callable));
}
private Completions()
{}
}
source
share