I have Scala code structured similarly to the following
for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
My understanding is in this code if either item1
or item2
resolves to None
then the whole chain of execution stops and the yield block isn't executed. You can see that item3
relies on item2
not being None, which it itself relies on item1
not being None.
I want to include error reporting but the best I could come up with while keeping the for-yield block was the following (Note: I'm reasonably new to Scala and functional programming, but realise the following isn't "Good Scala"):
val x = for {
item1 <- findItem1
item2 <- item1.get("item2_info")
} yield {
val item3 = createItem3(item2)
if (logic_using_item3) {
do something here
}
}
if (x == None) {
logger.error("Something went wrong")
}
What would be the correct "Scala way" to include error logging in this code to reflect something went wrong such as "Item1 was not found"
or "Item2 was empty"
. Can you do this in a for-yield block or will adding error logging require refactoring the code to not use a for-yield block?
The best, IMHO, would be to use an Either instead of an Option to keep the error message.
val result = for {
item1 <- findItem1.toRight(left = "Item1 was not found")
item2 <- item1.get("item2_info").toRight(left = "Item2 was not empty")
item3 = createItem3(item2)
if (logic_using_item3)
} yield foo
result match {
case Right(data) => ???
case Left(error) => logger.error(error)
}