Enjoy quickies with supplyAsync by knowing how to handle exceptions.
PROBLEM:
I have a method: public String getChuckNorrisFact();This method may also throw an exception, in my case IOException because this method does a service call to get a fact about Chuck Norris from web.
I learned about CompletableFuture and now I am ASYNCING the shit out everywhere.
Here is what I did:
CompletableFuture<String> factFuture = CompletableFuture.supplyAsync(() -> getChuckNorrisFact());
But the compiler tells me to handle or throw the exception, so I do this:
CompletableFuture<String> factFuture2 = CompletableFuture.supplyAsync(() -> {
try {
return getChuckNorrisFact();
} catch (IOException e) {
e.printStackTrace();
}
});
Sadly there is still a compilation error in this. The supplier(lambda expression) in supplyAsync() needs to return a string but there is no return statement if an exception occurs. So I do this:
CompletableFuture<String> factFuture = CompletableFuture.supplyAsync(() -> {
try {
return getChuckNorrisFact();
} catch (IOException e) {
return e.getMessage();
}
});
Voila! no compilation errors.
But there is still a problem with this code. Sometimes when I run this code I get dirt Exception message instead of Chuck Norris fact.
ಠ_ಠ
Solution:
Solution is simple, create a new object that encapsulates both Exceptions and result. Something like this:
public class ResultExceptionWrapper<T, E extends Exception> {
T result;
E exception;
}
Now return your result or exception encapsulated in this object, like this:
CompletableFuture<ResultExceptionWrapper<String, Exception>> factFuture = CompletableFuture.supplyAsync(() -> {
ChuckNorrisFact cnf = new ChuckNorrisFact();
try {
return new ResultExceptionWrapper<String, Exception>(cnf.getChuckNorrisFact(), null);
} catch (IOException e) {
Exception exception = new Exception(e);
return new ResultExceptionWrapper<String, Exception>(exception);
}
});
And to get the result do this:
ResultExceptionWrapper<String, Exception> factResponse = factFuture.get();
if(factResponse.getException()!=null){
// you can also create a custom exception and throw from here
System.out.println("Service call failed, no fact fetched.");
}
else{
System.out.println("Here is a Chuck Norris fact: "+factResponse.getResult());
}
This is just a simple way that gets the job done.
Peace.
Comments
Post a Comment