Optionals with unchecked exceptions - java

Consider the following code:
auditlog.getMessages()
.stream()
.filter(m -> messageId.equals(m.getMessageid()))
.findFirst()
.orElseThrow(NoMessageFoundException::new)
NoMessageFoundException is a custom unchecked exception, extending from RuntimeException. When findFirst() returns an empty optional I expect a NoMessageFoundException to be thrown, however, the code just carries on.
Is it impossible to do this with unchecked exceptions?
I could change NoMessageFoundException to a checked exception, but then I would have to write a try/catch block or some sort of wrapper to catch the exception as explained here but I wish to not do that.
Any ideas?

There is no limitation on the type of Exception that can be thrown.
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
If the code "carries on", it means that a message is found.

if the exception is not getting throw is because there is at least one element remaining after the filter action...
see this example:
public class ASFasf {
public static void main(String[] args) {
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5);
Integer iR = l.stream().filter(x -> x > 100).findFirst().orElseThrow(NoMessageFoundException::new);
System.out.println(iR);
}
}
class NoMessageFoundException extends RuntimeException {
public NoMessageFoundException() {
super("Opala!!");
}
}
iR will never get printed, and a NoMessageFoundException is thrown....

Related

java streams: elegant way to filter according an exception is thrown

Is there any more elegant way to filter according if an exception is thrown?
I mean, currently my code looks like:
stream.filter(item -> {
try {
validator.with(reference)
.hasAccess(this.authzManager)
.isOwner();
} catch (EspaiDocFault | DataAccessException e) {
return false;
}
return true;
}
)
What I'm trying to do is if an exception is thrown current item stream has to be filtered.
I'm looking for any existing util class or something similar...
A very common approach I've seen in many variations is to write own functional interface that will allow a checked exception to be thrown (1) and to adapt that solution to a built-in interface (2).
/**
* An EPredicate is a Predicate that allows a checked exception to be thrown.
*
* #param <T> the type of the input to the predicate
* #param <E> the allowed exception
*/
#FunctionalInterface
public interface EPredicate<T, E extends Exception> {
/**
* (1) the method permits a checked exception
*/
boolean test(T t) throws E;
/**
* (2) the method adapts an EPredicate to a Predicate.
*/
static <T, E extends Exception> Predicate<T> unwrap(EPredicate<T, E> predicate) {
return t -> {
try {
return predicate.test(t);
} catch (Exception e) {
return false;
}
};
}
}
An example looks quite elegant:
.stream()
.filter(EPredicate.<ItemType, Exception>unwrap(item -> validator.[...].isOwner()))
where,
ItemType is the type of item;
Exception is a common parent of EspaiDocFault and DataAccessException.
.stream()
.filter(EPredicate.unwrap(item -> validator.[...].isOwner()))
The Vavr library has a Try class that can do what you want:
stream.filter(item -> Try.of(() -> validator.with(reference)
.hasAccess(this.authzManager)
.isOwner()).getOrElse(false))
Edit: if you actually want to know whether the exception was thrown or not, Vavr can do that too:
stream.filter(item -> Try.of([...]).isSuccess())
Alternatively, wrap the whole thing in a method:
stream.filter(this::getMyBooleanWithinMyTry)

Is it right way for handling exceptions using Apache ExceptionUtils.getRootCause?

Is it possible, that below condition in "My code" will be fulfilled(true)? I belive that no, beacuse getRootCause returns object casted to Throwable. So it should check, if Throwable is a subtype of MyOwnException, which is not true. So, in general, it is wrong way to use getRootCause to handle exceptions, is not it?
MyOwnException part
public class MyOwnException extends Exception {
// ....
}
Apache's ExceptionUtils.getRootCause
public static Throwable getRootCause(Throwable throwable) {
List list = getThrowableList(throwable);
return (list.size() < 2 ? null : (Throwable)list.get(list.size() - 1));
}
My code
try {
// do something
} catch (Exception e) {
try {
Throwable exc = ExceptionUtils.getRootCause(e);
if (exc instanceof MyOwnException) {
// do something
}
}
}
instanceof will check against the actual run-time type of an object instance. It does not matter what the declared compile-time type of the variable that holds the object is.
So your condition works: If the root cause is a MyOwnException then your if block's body will execute.

How to chain lambdas with all optional values available at the innermost scope without nesting Optional#ifPresent()?

This is an offshoot of my other question: How to chain Optional#ifPresent() in lambda without nesting?
However, the problem now is how to provide a lambda solution where all of the optional values are available at the innermost scope:
B b = procA().flatMap(this::procB).orElseThrow(SomeException::new);
// Value from procA() is not available.
My original code was:
void SomeMethod() {
procA().ifPresent(a -> {
procB(a).ifPresent(b -> {
// Do something with a and b
return;
});
});
throw new SomeException();
}
I understand that the return at the innermost scope is wrong. The new flatMap example illustrates the correct behavior.
I am using ifPresent() instead of get() to avoid potential runtime exceptions where I might fail to check whether the value of an optional isPresent().
I find this question very interesting as chained calls with potential null returns are a common nuisance, and Optional can shorten the usual null check chain a lot. But the issue there is that the nature of the functional stream methods hides the intermediate values in the mapping functions. Nesting is a way to keep them available, but can also get annoying if the length of the call chain grows, as you have realized.
I cannot think of an easy and lightweight solution, but if the nature of your project leads to these situations regularly, this util class could help:
public static class ChainedOptional<T>
{
private final List<Object> intermediates;
private final Optional<T> delegate;
private ChainedOptional(List<Object> previousValues, Optional<T> delegate)
{
this.intermediates = new ArrayList<>(previousValues);
intermediates.add(delegate.orElse(null));
this.delegate = delegate;
}
public static <T> ChainedOptional<T> of(T value)
{
return of(Optional.ofNullable(value));
}
public static <T> ChainedOptional<T> of(Optional<T> delegate)
{
return new ChainedOptional<>(new ArrayList<>(), delegate);
}
public <R> ChainedOptional<R> map(Function<T, R> mapper)
{
return new ChainedOptional<>(intermediates, delegate.map(mapper));
}
public ChainedOptional<T> ifPresent(Consumer<T> consumer)
{
delegate.ifPresent(consumer);
return this;
}
public ChainedOptional<T> ifPresent(BiConsumer<List<Object>, T> consumer)
{
delegate.ifPresent(value -> consumer.accept(intermediates, value));
return this;
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X
{
return delegate.orElseThrow(exceptionSupplier);
}
public <X extends Throwable> T orElseThrow(Function<List<Object>, X> exceptionSupplier)
throws X
{
return orElseThrow(() -> exceptionSupplier.apply(intermediates));
}
}
You use it by wrapping an Optional or a plain value. When you then use the map method to chain method calls, it will provide a new ChainedOptional while storing the current value in a list. At the end (ifPresent, orElseThrow), you will not only get the last value, but also the list of all intermediate values. Since it is not known how many calls will be chained, I did not find a way to store those values in a type-safe way, though.
See examples here:
ChainedOptional.of(1)
.map(s -> s + 1)
.map(s -> "hello world")
.map(s -> (String) null)
.map(String::length)
.ifPresent((intermediates, result) -> {
System.out.println(intermediates);
System.out.println("Result: " + result);
})
.orElseThrow(intermediates -> {
System.err.println(intermediates);
return new NoSuchElementException();
});
// [1, 2, hello world, null, null]
// Exception in thread "main" java.util.NoSuchElementException
// at ...
ChainedOptional.of(1)
.map(s -> s + 1)
.map(s -> "hello world")
// .map(s -> (String) null)
.map(String::length)
.ifPresent((intermediates, result) -> {
System.out.println(intermediates);
System.out.println("Result: " + result);
})
.orElseThrow(intermediates -> {
System.err.println(intermediates);
return new NoSuchElementException();
});
// [1, 2, hello world, 11]
// Result: 11
Hope this helps. Let me know if you come up with a nicer solution.

Java 8 Stream. Throw exception to client method inside lambda expression

I've seen a few questions related to this, but I need a clear answer. I do understand the context where lambda expressions run, and the concept of side effects, but I believe there is a workaround I'm not seeing here.
I need to map a list of personas based on their sex, but the method I use to determine their sex returns a checked exception, which is not something the Collectors.groupingBy likes, at all.
Getting rid of the checked exception is not an option, and I need to send it up to the client method who invoked my piece of code. I there anything I can do around it?
public class Example {
public static void main(String[] args) {
Example example = new Example();
try {
example.runExample();
} catch (MException e) {
//Place where I want to handle the exception
}
}
private void runExample() throws MException{
List<Person> personas = Arrays.asList(new Person("Sergio", "234456789", 35), new Person("Mariana", "123456789", 38));
Map<String, List<Person>> personsBySex = personas.stream().collect(Collectors.groupingBy(persona -> {
try {
return getSex(persona.getSSN());
} catch (MException e) {
}
return null;
//Compiler forces me to return a value, but I don't want to return null.
//I want to throw up the MException to the client method (main)
}));
}
private String getSex(String ssn) throws MException {
// Imagine here is a call to an outside service that would give me the
// sex based on the SSN, but this service could return an exception as
// well
if (ssn.isEmpty())
throw new MException();
return ssn.startsWith("1") ? "Female" : "Male";
}
}
class Person {
private String name, ssn;
private Integer age;
public Person(String name, String ssn, Integer age) {
this.name = name;
this.ssn = ssn;
this.age = age;
}
public String getName() {return name;}
public String getSSN() {return ssn;}
public Integer getAge() {return age;}
}
class MException extends Exception {
}
Thanks for any ideas!
A workaround could be wrapping your checked exception with an unchecked one and throwing the latter from the catch block. Note that we are saving an MException as a cause to be able to work with further.
try {
return getSex(persona.getSSN());
} catch (MException e) {
throw new IllegalArgumentException(e); // choose a suitable runtime one
}
Another way to go (rather a modification of the previous one, I don't like that) would be writing a Collectors.groupingBy-friendly method to move the foregoing logic into:
private String getSexFriendly(String ssn) {
try {
return getSex(ssn);
} catch (MException e) {
throw new IllegalArgumentException(e);
}
}
Though, we will have a good-looking lambda:
persona -> getSexFriendly(persona.getSSN())
Forget about wrapping your exception - you can utilize the "sneaky throws' hack here which enables you to trick the compiler to think that your exception is not checked - this exploits the type inference rule introduced in Java 8.
Let's recreate your problem:
public Integer toInteger(String string) throws IOException {
throw new IOException("whoopsie!");
}
Stream.of("42")
.collect(Collectors.groupingBy(o -> toInteger(o))); // does not compile
Usually, you'd need to try-catch the exception just like you did, but there is a workaround:
#Test
public void example_1() throws Exception {
Stream.of("42")
.collect(Collectors.groupingBy(unchecked(this::toInteger)));
}
public Integer toInteger(String string) throws IOException {
throw new IOException("whoopsie!");
}
private static <T, R> Function<T, R> unchecked(ThrowingFunction<T, R> f) {
return t -> {
try {
return f.apply(t);
} catch (Throwable thr) {
return ThrowingFunction.sneakyThrow(thr);
}
};
}
public interface ThrowingFunction<T, R> {
R apply(T t) throws Throwable;
#SuppressWarnings("unchecked")
static <T extends Throwable, R> R sneakyThrow(Throwable t) throws T {
throw (T) t;
}
}
Firstly, you need to create your own functional interface for representing a function that can throw exceptions. In this case, ThrowingFunction.
Then, you can create a utility method that will repackage your checked lambda into a standard java.util.function. In this case, unchecked().
The last step is to create a method that sneakily throws an exception. In this case, sneakyThrow().
Actually, I think I will write an article about this.
EDIT:
I wrote: http://4comprehension.com/sneakily-throwing-exceptions-in-lambda-expressions-in-java/

Is there a nicer (java8?) way to collect the "cause stack" of an exception?

We have a BaseException extends Exception in our project, and basically all our other exceptions derive from this class. I want to change some methods that deal with the "cause stack" at runtime.
As starting point, I wrote the following method:
class BaseException extends Exception {
...
/**
* Helper: creates a list containing the complete "cause stack" of this exception.
* Please note: the exception on which this method is called is part of result!
*
* #return a {#link List} of all "causes" of this exception
*/
List<Throwable> getAllCauses() {
Throwable cause = this;
List<Throwable> causes = new ArrayList<>();
while (cause != null) {
causes.add(cause);
cause = cause.getCause();
}
return causes;
}
This gets the job done, although it is not perfect (name isn't exactly great, and single layer of abstraction is violated, too) .
But still: is there a "more elegant" way of collecting this result? Especially given the fact that it would helpful to directly return a Stream<Throwable>.
( I am mainly wondering if there is a java8 lambda/idiom that could help here )
This article should be of help. In particular,
Stream<Throwable> causes(Throwable t){
if (t == null) return Stream.empty();
return Stream.concat(Stream.of(t), causes(t.getCause()));
}
Here is my implementation that implemented by Spliterator as below:
public static <T> Stream<T>
iterateUntil(T seed, UnaryOperator<T> generator, Predicate<T> proceed){
return stream(new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED){
private T value = seed;
public boolean tryAdvance(Consumer<? super T> action){
if(!proceed.test(value)) return false;
action.accept(value);
value = generator.apply(value);
return true;
}
}, false);
}
Then you can implements your getCauses as below and it drop the recursive calls:
List<Throwable> getAllCauses() {
return iterateUntil(this, Throwable::getCause, Objects::nonNull)
.collect(toList());
}
Using some enumeration seems more appropriate to me, then something like
class BaseException extends Exception {
...
Enumeration<Throwable> getCauses() {
return new Enumeration<Throwable>() {
private Throwable current = BaseException.this;
public boolean hasMoreElements() {
return current != null;
}
public Throwable nextElement() {
Throwable c = current;
current = current.getCause();
return c;
}
}
}
With Java 8 you can also create a new interface with a default method doing the trick and then use that interface in any of your exception class (slightly better than subclassing Exception?).

Categories