Prettifying exception handling in function - java

Can this func. not be prettified?
Can the the catch clause be left empty, I have heard it's frowned up on.
apiClient.accountList() is where the exception can occur.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
try {
for (Account account : apiClient.accountList()) {
if (account.getUuid().equals(accountUuid)) {
return Optional.of(account);
}
}
} catch (ApiException e) {
return Optional.empty();
}
return Optional.empty();
}

If you're very motivated to avoid the duplicate return statement, a simple tweak to the control-flow should do it. As mentioned in the comments, logging exceptions is often a good idea.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
Optional<Account> result = Optional.empty();
try {
for (Account account : apiClient.accountList()) {
if (account.getUuid().equals(accountUuid)) {
result = Optional.of(account);
break;
}
}
}
catch (ApiException e) { /* Log exception */ }
return result;
}

You can use Stream, assuming getUuid does not throw an ApiException.
public Optional<Account> getAccount(String accountUuid) throws ApiException {
try {
return apiClient.accountList().stream()
.filter(account -> account.getUuid().equals(accountUuid))
.findAny();
} catch (ApiException e) {
/* Log exception */
return Optional.empty();
}
}
Actually instead of collection returning methods like accountList() it more and more makes sense to use Streams, accountStream().

Related

Why java streams are not able to handle exception even after surrounding with a try-catch block?

I have the following piece of code with java streams
You can see that I am having an error on the 4th line. Basically the error says Unhandled Exception: AddressException. But you can see that I am catching it within catch block. But still that is not working. Eventhough, if I use a try catch block within the map method it works as shown below
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails){
List<InternetAddress> internetAddresses = new ArrayList<>();
internetAddresses = toEmails.stream().map(a->{
InternetAddress ia = null;
try{
ia = new InternetAddress(a);
} catch (AddressException e) {
}
return ia;
}).collect(Collectors.toList());
return internetAddresses;
}
Does anyone know why this behaviour and if knows please give some insights to that. One more quetion, does the anonymous inner class will also behave the same ?
Error is shown because you provided method with different signature (additional thows clause). You have to provide implementation that is compatible with java.util.function.Function#apply signature
R apply(T var1);
There is several ways to deal with your problem:
anonymous function with try-catch
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
return toEmails.stream().map(new Function<String, InternetAddress>() {
#Override
public InternetAddress apply(String email) {
try {
return new InternetAddress(email);
} catch (AddressException e) {
e.printStackTrace();
}
return null;
}
}).collect(Collectors.toList());
}
try-catch in lambda
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
return toEmails.stream().map(email -> {
try {
return new InternetAddress(email);
} catch (AddressException e) {
e.printStackTrace();
}
return null;
}).collect(Collectors.toList());
}
extracted handling method
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
return toEmails.stream().map(this::createInternetAddress).collect(Collectors.toList());
}
private InternetAddress createInternetAddress(String email) {
try {
return new InternetAddress(email);
} catch (AddressException e) {
e.printStackTrace();
}
return null;
}
generalized extracted handling method
#FunctionalInterface
public interface FunctionThrowing <T, R, E extends Exception> {
R apply(T var1) throws E;
static <T, R, E extends Exception> Function<T, R> handled(FunctionThrowing<T, R, E> ft) {
return result -> {
try {
return ft.apply(result);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}
}
public List<InternetAddress> getListOfInternetEmailAddresses(List<String> toEmails) {
List<InternetAddress> internetAddresses = new ArrayList<>();
internetAddresses = toEmails.stream().map(FunctionThrowing.handled(InternetAddress::new)).collect(Collectors.toList());
return internetAddresses;
}

Why does sonar think this expression is always false

In my Java project SonarQube says that an expression is always false. However I cannot see why. This is the code in question:
BaseException baseException = null;
for (SpaceInfo i: spaceInfos) {
try {
processSingle(i.getSpaceKey(), i.getContentType());
} catch (BaseException e) {
baseException = BaseException.chain(baseException, e);
}
}
// Here sonar say that this condition will always evaluate to false.
if (baseException != null) {
throw baseException;
}
However in my opinion if the processSingle method throws a BaseException then baseException should not be null and therefore the expression should not evaluate to false.
The processSingle method is declared as follows:
private void processSingle(String spaceKey, String contentType) throws BaseException
And there are definitely cases in which the processSingle method will throw a BaseException. So I think that Sonar is mistaken. Or is there something going on here that I am not seeing?
Update:
This is what BaseException.chain() does:
public static BaseException chain (BaseException a, BaseException b) {
if (a == null) { return b; }
a.setNextException(b);
return a;
}
And this is the code of processSingle:
private void processSingle(String spaceKey, String contentType) throws BaseException {
assert ContentTypes.Page.equals(contentType) || ContentTypes.BlogPost.equals(contentType);
Content content;
try {
content = createEmptyContent(spaceKey, contentType);
} catch (Exception e) {
throw new MessageToContentProcessorProcessSingleException(contentType, spaceKey, e);
}
BaseException baseException = null;
try {
contentCreator.addMetadata(content);
} catch (BaseException e) {
baseException = BaseException.chain(baseException, e);
}
Pair<List<AttachmentInfo>, FailedToSaveAttachmentException> pair = contentCreator.saveAttachments(messageParser.getContent(), content);
List<AttachmentInfo> attachments = pair.getLeft();
baseException = BaseException.chain(baseException, pair.getRight());
try {
String html = htmlGenerator.generateHtml(attachments, messageParser.getContent());
contentCreator.updateBodyOfContent(content, html);
} catch (BaseException e) {
baseException = BaseException.chain(baseException, e);
}
if (baseException != null) {
throw new MessageToContentProcessorProcessSingleException(contentType, spaceKey, baseException);
}
}
Just for testing/curiosity, I would try:
} catch (BaseException e) {
baseException = e;
}
this would show if Sonar thinks the exception can be thrown or not. Or if it is getting confused by the chain method or assignment statement (assigning to basseException but using it (still null) on the right side of assignment).
I know this is changing the logic, just for testing
even try (but I do not believe this would trick Sonar)
} catch (BaseException e) {
var tmp = BaseException.chain(baseException, e);
baseException = tmp;
}
Try changing chain() to help SonarQube:
public static BaseException chain (BaseException a, BaseException b) {
if (a == null) {
return b;
} else {
a.setNextException(b);
return a;
}
}
thinking about it, hardly possible to be the problem - almost trivial that a is not null here
I would try and see if it works:
BaseException baseException;
for (SpaceInfo i: spaceInfos) {
try {
processSingle(i.getSpaceKey(), i.getContentType());
baseException = null;
} catch (BaseException e) {
baseException = BaseException.chain(baseException, e);
}
}

How to avoid dummy return in try catch block while a method which throws exception is called?

I know it is required that in a non-void method, return or throw is a must.
But I don't like the dummy return in catch block in such case:
public int call() throws Exception {
try {
return calcMethod();
} catch (Exception e) {
process(e);
return 0;
}
}
protected void process(Exception e) throws xxxException {
if ( isTypeAException(e) ) { throw new TypeAException() ; }
else if ( isTypeBException(e) ) { throw new TypeBException() ; }
else ( isTypeCException(e) ) { throw new TypeCException() ; }
}
...
process will certainly throws an exception, then why return is still required in catch block?
In one sense, throwing the exception in process() is to be construed as "a problem with processing", which is also not what you mean.
As you want the exception to be raised by call(), so the solution here is to make process() an exception factory:
public int call() throws Exception {
try {
return calcMethod();
} catch (Exception e) {
throw process(e);
}
}
protected xxxException process(Exception e) throws xxxException {
if (isTypeAException(e))
return new TypeAException();
else if (isTypeBException(e))
return new TypeBException();
else
return new TypeCException();
}

Java - How to throw exception outside an anonymous class

try
{
if(ruleName.equalsIgnoreCase("RuleName"))
{
cu.accept(new ASTVisitor()
{
public boolean visit(MethodInvocation e)
{
if(rule.getConditions().verify(e, env, parentKeys, astParser, file, cu)) // throws ParseException
matches.add(getLinesPosition(cu, e));
return true;
}
});
}
// ...
}
catch(ParseException e)
{
throw AnotherException();
}
// ...
I need to catch thrown exception in the bottom catch, but I cannot overload method via throws construction. How to do with that, please advice? Thanks
Create custom exception, write try catch block in anonymous class and catch it in your catch block.
class CustomException extends Exception
{
//Parameterless Constructor
public CustomException () {}
//Constructor that accepts a message
public CustomException (String message)
{
super(message);
}
}
now
try
{
if(ruleName.equalsIgnoreCase("RuleName"))
{
cu.accept(new ASTVisitor()
{
try {
public boolean visit(MethodInvocation e)
{
if(rule.getConditions().verify(e, env, parentKeys, astParser, file, cu)) // throws ParseException
matches.add(getLinesPosition(cu, e));
return true;
}
catch(Exception e){
throw new CustomException();
}
});
}
// ...
}
catch(CustomException e)
{
throw AnotherException();
}
As suggested already, an unchecked exception could be used. Another option is to mutate a final variable. Eg:
final AtomicReference<Exception> exceptionRef = new AtomicReference<>();
SomeInterface anonymous = new SomeInterface() {
public void doStuff() {
try {
doSomethingExceptional();
} catch (Exception e) {
exceptionRef.set(e);
}
}
};
anonymous.doStuff();
if (exceptionRef.get() != null) {
throw exceptionRef.get();
}

Is there an easy way to turn Future<Future<T>> into Future<T>?

I've got some code that submits a request to another thread which may or may not submit that request to yet another thread. That yields a return type of Future<Future<T>>. Is there some non-heinous way to immediately turn this into Future<T> that waits on the completion of the entire future chain?
I'm already using the Guava library to handle other fun concurrency stuff and as a replacement for Google Collections and its working well but I can't seem to find something for this case.
Another possible implementation that uses the guava libraries and is a lot simpler.
import java.util.concurrent.*;
import com.google.common.util.concurrent.*;
import com.google.common.base.*;
public class FFutures {
public <T> Future<T> flatten(Future<Future<T>> future) {
return Futures.chain(Futures.makeListenable(future), new Function<Future<T>, ListenableFuture<T>>() {
public ListenableFuture<T> apply(Future<T> f) {
return Futures.makeListenable(f);
}
});
}
}
Guava 13.0 adds Futures.dereference to do this. It requires a ListenableFuture<ListenableFuture>, rather than a plain Future<Future>. (Operating on a plain Future would require a makeListenable call, each of which requires a dedicated thread for the lifetime of the task (as is made clearer by the method's new name, JdkFutureAdapters.listenInPoolThread).)
I think this is the best that can be done to implement the contract of Future. I took the tack of being as unclever as possible so as to be sure that it meets the contract. Not especially the implementation of get with timeout.
import java.util.concurrent.*;
public class Futures {
public <T> Future<T> flatten(Future<Future<T>> future) {
return new FlattenedFuture<T>(future);
}
private static class FlattenedFuture<T> implements Future<T> {
private final Future<Future<T>> future;
public FlattenedFuture(Future<Future<T>> future) {
this.future = future;
}
public boolean cancel(boolean mayInterruptIfRunning) {
if (!future.isDone()) {
return future.cancel(mayInterruptIfRunning);
} else {
while (true) {
try {
return future.get().cancel(mayInterruptIfRunning);
} catch (CancellationException ce) {
return true;
} catch (ExecutionException ee) {
return false;
} catch (InterruptedException ie) {
// pass
}
}
}
}
public T get() throws InterruptedException,
CancellationException,
ExecutionException
{
return future.get().get();
}
public T get(long timeout, TimeUnit unit) throws InterruptedException,
CancellationException,
ExecutionException,
TimeoutException
{
if (future.isDone()) {
return future.get().get(timeout, unit);
} else {
return future.get(timeout, unit).get(0, TimeUnit.SECONDS);
}
}
public boolean isCancelled() {
while (true) {
try {
return future.isCancelled() || future.get().isCancelled();
} catch (CancellationException ce) {
return true;
} catch (ExecutionException ee) {
return false;
} catch (InterruptedException ie) {
// pass
}
}
}
public boolean isDone() {
return future.isDone() && innerIsDone();
}
private boolean innerIsDone() {
while (true) {
try {
return future.get().isDone();
} catch (CancellationException ce) {
return true;
} catch (ExecutionException ee) {
return true;
} catch (InterruptedException ie) {
// pass
}
}
}
}
}
You could create a class like:
public class UnwrapFuture<T> implements Future<T> {
Future<Future<T>> wrappedFuture;
public UnwrapFuture(Future<Future<T>> wrappedFuture) {
this.wrappedFuture = wrappedFuture;
}
public boolean cancel(boolean mayInterruptIfRunning) {
try {
return wrappedFuture.get().cancel(mayInterruptIfRunning);
} catch (InterruptedException e) {
//todo: do something
} catch (ExecutionException e) {
//todo: do something
}
}
...
}
You'll have to deal with exceptions that get() can raise but other methods cannot.
This was my first stab at it but I'm sure there is plenty wrong with it. I'd be more than happy to just replace it with something like Futures.compress(f).
public class CompressedFuture<T> implements Future<T> {
private final Future<Future<T>> delegate;
public CompressedFuture(Future<Future<T>> delegate) {
this.delegate = delegate;
}
#Override
public boolean cancel(boolean mayInterruptIfRunning) {
if (delegate.isDone()) {
return delegate.cancel(mayInterruptIfRunning);
}
try {
return delegate.get().cancel(mayInterruptIfRunning);
} catch (InterruptedException e) {
throw new RuntimeException("Error fetching a finished future", e);
} catch (ExecutionException e) {
throw new RuntimeException("Error fetching a finished future", e);
}
}
#Override
public T get() throws InterruptedException, ExecutionException {
return delegate.get().get();
}
#Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
long endTime = System.currentTimeMillis() + unit.toMillis(timeout);
Future<T> next = delegate.get(timeout, unit);
return next.get(endTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
#Override
public boolean isCancelled() {
if (!delegate.isDone()) {
return delegate.isCancelled();
}
try {
return delegate.get().isCancelled();
} catch (InterruptedException e) {
throw new RuntimeException("Error fetching a finished future", e);
} catch (ExecutionException e) {
throw new RuntimeException("Error fetching a finished future", e);
}
}
#Override
public boolean isDone() {
if (!delegate.isDone()) {
return false;
}
try {
return delegate.get().isDone();
} catch (InterruptedException e) {
throw new RuntimeException("Error fetching a finished future", e);
} catch (ExecutionException e) {
throw new RuntimeException("Error fetching a finished future", e);
}
}
}

Categories