---
# System prepended metadata

title: Question

---

# Question
Implement the function `retrieveAddress` using the methods `getStreet1`, `getStreet2`, and `getStreet3` to create an `Address`.

```scala
case class Address(
  street1: String,
  street2: String,
  street3: Option[String]
)

sealed trait ApplicationError

sealed trait NonExistingAddress extends ApplicationError

case class NoStreet1() extends NonExistingAddress

def retrieveAddress: Either[ApplicationError, Address] = {
    // TODO: Implement
    val street1: Option[String] = Try(getStreet1).toOption
    val street2: Option[String] = try {
        Some(getStreet2)
    } catch {
        case e: Exception => None
    }
    val street3: Option[String] = try {
        Some(getStreet3)
    } catch {
        case e: Exception => None
    }
    // street1.map(s1 => Right(Address(s1, street2, street3))).getOrElse(Left(NonExistingAddress))
    
    (street1, street2) match {
        case (None, _) => Left(NonExistingAddress)
        case (_, None) => Left(NonExistingAddress)
        case (Some(s1), Some(s2)) => Right(Address(s1, s2, street3))
    }
}

// =======================================================================  
// LIBRARY METHODS 
// =======================================================================
/**
  * Retrieves the main street address.
  * @throws RuntimeException if empty
  */
def getStreet1: String = {
  // implementation
}
/**
  * Retrieves additional street address line 2.
  * @throws RuntimeException if empty
  */
def getStreet2: String = {
  // implementation
}
/**
  * Retrieves additional street address line 3.
  * @throws RuntimeException if empty
  */
def getStreet3: String = {
  // implementation
}