On Github lindseydew / coding-for-unhappy-paths
def processContent():
  url = "http://content.guardianapis.com/technology"
  response = urllib2.urlopen(url)
  data = response.read()
  results = json.loads(data).get('response', {}).get('results', [])
  for r in results:
    body = r.get('fields', {}).get('body', '')
    if body:
      cleantext = BeautifulSoup(body).text
      f = open("technology.txt", 'a')
      f.write(cleantext.encode('utf-8'))
      f.write('\n')
      f.close()	
				Reading an external resource and storing in memory
Design our functions to return a computation context which can be explicitly type checked when used
sealed trait Option[A] case class Some[A](a: A) extends Option[A] case class None extends Option[A]
public class HelloWorld { 
   public static void main(String[] args) { 
      User user = findUser(1234)
      if(user != null) {
      	//continue with the program
  	  }
   }
   public User findUser(Int i)
} 					
				object OptionExample {
 def main(args: Array[String]) {
    val user: User = findUser(1234)
    //doesn't compile -> this is an option
  }
  
 def findUser(i: Int): Option[User]
} 					
object OptionExample {
 def main(args: Array[String]) {
    val user: Option[User] = findUser(1234)
   	user match {
   		case Some(u) => //continue with your program
   		case None => //handle this
   	}
  }
  
 def findUser(i: Int): Option[User]
} 					
Reading an external resource and storing in memory
sealed trait Either[+E,+A] case class Left[+E](get: E) extends Either[E,Nothing] case class Right[+A](get: A) extends Either[Nothing,A]
def fileFromWeb(key: String, bucketName: String): Either[Error, File] = {
    try {
      Right(getFile(key, bucketName))
    } catch {
      case NonFatal(e) => Left(Error(s"error reading the s3 
      cache ${e}"))
    }
  }
				val file = getFileFromWeb()
file match {
  case Right(f) => //continue our execution
  case Left(error) => Log.error(error)
}
				val file = getFileFromWeb()
file match {
  case Right(f) => readContents(f) match {
  		case Right(contents) => //continue
  		case Left(error) => Log.error(error)
	}
  case Left(error) => Log.error(error)
}
			def method1(): Either[E, A]
def method2(a: A): Either[E, B]
for {
  a <- method1().right
  b <- method2(a).right
} yield b
				def populateCache(): Either[PermissionsReaderError, Date] = {
    for {
      obj <- getFileFromWeb(key, bucket).right
      data <- readContents(obj).right
      permissions <- parseFileConents(data.contents).right
      _ = storePermissionsData(permissions)
    } yield data.lastMod
  }	
  populateCache() match {
      case Right(d) => Logger.info(s"successfully updated permissions cache with last modified time ${d}")
      case Left(error) => Logger.error("error updating permissions 
      cache " + error)
    }