Open laurent-thiebaud-gisaia opened 5 years ago
Hi @laurent-thiebaud-gisaia ,
The IO monad in cyclops provides some support for checked exceptions. If you just wanted to log errors you could write something like this
IO.sync(myList)
.checkedMap(My::mayThrowCheckedException)
.forEach(System.out::println,System.err::println,()->System.out.println("Complete"));
In the forEach method we can provide consumers for each processed element, each error and the complete signal.
There is also a mapTry operator which can do the mapping directly to a Try, if we don't want to handle errors separately. mapTry doesn't directly support checked exceptions, but we can plugin the ExceptionSoftener for that :
import static com.oath.cyclops.util.ExceptionSoftener.softenFunction;
IO.sync(myList)
.mapTry(softenFunction(My::mayThrowCheckedException))
Rather than use failureGet, if we convert our Try to en Either type we can call map on the 'left' side of the Either.
IO.sync(myList)
.mapTry(softenFunction(My::mayThrowCheckedException))
.map(Try::toEither)
.map(e->e.mapLeft(Throwable::getMessage))
And to finish convert to a String
IO.sync(myList)
.mapTry(softenFunction(My::mayThrowCheckedException))
.map(Try::toEither)
.map(e->e.mapLeft(Throwable::getMessage))
.map(e->e.leftOrElse("No Exception"))
.stream()
.collect(Collectors.joining(","));
Hi,
I was able to make my code clearer using the either, thank you. However the following:
IO.sync(myList)
.mapTry(softenFunction(My::mayThrowCheckedException))
doesn't compile because
non static method cannot be referenced from a static context java
It may depend on your classes. Is my a variable or a class? I created a simple class called My.
static class My{
public String mayThrowCheckedException() throws Exception{
throw new RuntimeException("Erorr thrown");
}
}
List<My> myList = Arrays.asList(new My(), new My(), new My());
String errorMessage = IO.sync(myList)
.mapTry(softenFunction(My::mayThrowCheckedException))
.map(Try::toEither)
.map(e->e.mapLeft(Throwable::getMessage))
.map(e->e.leftOrElse("No Exception"))
.stream()
.collect(Collectors.joining(","));
This compiles, but probably doesn't quite match your classes.
Does it not make sense to convert
.map(Try::toEither)
.map(e->e.mapLeft(Throwable::getMessage))
.map(e->e.leftOrElse("No Exception"))
to
.map(t -> t.fold(s -> "No Exception", e->e.getMessage()))
Yes, that is much neater
Suppose this example of code:
aStream.foreach(object -> consumeObjectMayThrowCheckedException())
This will not compile because of the checked exception. I think that the state of art, in functional programming, is to process the stream, then get the list of thrown exception to handle it (let's say in order to log it). I've been using the following code, that I don't like:
What would be the proper to achieve it? What is the state of the art using Cyclops?
Thanks.