Search code examples
scalafor-comprehensionscala-option

Adding logging if return value is None


Suppose there are two functions findUser(id:String):Option[User] and findAddress(user:User):Option[Address] invoked as follows:

for(user <- findUser(id); address <- findAddress(user)) println(address)

Now I would like to add error logging to this for-comprehension. I would like to call a log(msg:String) function if either user or address is not found.

for(user <- findUser(id) ifNone log("user not found"); 
    address <- findAddress(user) ifNone log("address not found")) 
       println(address)

Can I do it without changing the function signatures?


Solution

  • Maybe

    implicit def withIfNone[A](o: Option[A]) = new {
      def ifNone(action: => Unit) = { if (o == None) action; o }
    }
    

    You may also consider using Either instead of option (or converting your options to Either). That would not work with a foreach (a for without a yield), but you might do

    for(
      a <- option1.toRight("option1 missing").right; 
      b <- option2.toRight("option2 missing").right)
    yield f(a,b)
    

    Then you can pattern match on the result with

    case Left(error) => log (error)
    case Right(result) => // use result