Buscar..


Tratar

Usando Try with map , getOrElse y flatMap :

import scala.util.Try

val i = Try("123".toInt)     // Success(123)
i.map(_ + 1).getOrElse(321)  // 124

val j = Try("abc".toInt)     // Failure(java.lang.NumberFormatException)
j.map(_ + 1).getOrElse(321)  // 321

Try("123".toInt) flatMap { i =>
  Try("234".toInt)
    .map(_ + i)
}                            // Success(357)

Usando Try con el patrón de coincidencia:

Try(parsePerson("John Doe")) match {
    case Success(person) => println(person.surname)
    case Failure(ex) => // Handle error ...
}

Ya sea

Diferentes tipos de datos para error / éxito

def getPersonFromWebService(url: String): Either[String, Person] = {
    
    val response = webServiceClient.get(url)

    response.webService.status match {
        case 200 => {
            val person = parsePerson(response)
            if(!isValid(person)) Left("Validation failed")
            else Right(person)
        }

        case _ => Left(s"Request failed with error code $response.status")
    }
}

Coincidencia de patrones en cualquier valor

getPersonFromWebService("http://some-webservice.com/person") match {
    case Left(errorMessage) => println(errorMessage)
    case Right(person) => println(person.surname)
}

Convertir cualquier valor a opción

val maybePerson: Option[Person] = getPersonFromWebService("http://some-webservice.com/person").right.toOption

Opción

El uso de valores null no se recomienda, a menos que se interactúe con el código Java heredado que se espera que sea null . En su lugar, la Option debería usarse cuando el resultado de una función puede ser algo ( Some ) o nada ( None ).

Un bloque try-catch es más apropiado para el manejo de errores, pero si la función no puede devolver nada legítimamente, la Option es apropiada para el uso y es simple.

Una Option[T] puede ser Some(value) (contiene un valor de tipo T ) o None :

def findPerson(name: String): Option[Person]

Si no se encuentra ninguna persona, None puede ser devuelta. De lo contrario, se devuelve un objeto de tipo Some contienen un objeto Person . Lo que sigue son formas de manejar un objeto de tipo Option .

La coincidencia de patrones

findPerson(personName) match {
    case Some(person) => println(person.surname)
    case None => println(s"No person found with name $personName")
}

Usando map y getOrElse

val name = findPerson(personName).map(_.firstName).getOrElse("Unknown")
println(name) // Prints either the name of the found person or "Unknown"

Utilizando pliegue

val name = findPerson(personName).fold("Unknown")(_.firstName)
// equivalent to the map getOrElse example above.

Convertir a Java

Si necesita convertir un tipo de Option a un tipo de Java con capacidad nula para la interoperabilidad:

val s: Option[String] = Option("hello")
s.orNull           // "hello": String
s.getOrElse(null)  // "hello": String

val n: Option[Int] = Option(42)
n.orNull           // compilation failure (Cannot prove that Null <:< Int.)
n.getOrElse(null)  // 42

Manejo de errores originados en futuros

Cuando se lanza una exception desde un Future , puede (debería) usar recover para manejarlo.

Por ejemplo,

def runFuture: Future = Future { throw new FairlyStupidException }

val itWillBeAwesome: Future = runFuture

... lanzará una Exception desde dentro del Future . Pero viendo que podemos predecir una Exception de tipo FairlyStupidException con una alta probabilidad, podemos manejar este caso específicamente de una manera elegante:

val itWillBeAwesomeOrIllRecover = runFuture recover { 
    case stupid: FairlyStupidException => 
         BadRequest("Another stupid exception!") 
}

Como puede ver, el método dado para recover es un PartialFunction sobre el dominio de todos los Throwable , por lo que puede manejar solo algunos tipos y luego dejar que el resto entre en el nivel de manejo de excepciones en los niveles más altos en la pila Future .

Tenga en cuenta que esto es similar a ejecutar el siguiente código en un contexto no Future :

def runNotFuture: Unit = throw new FairlyStupidException

try {
    runNotFuture
} catch {
    case e: FairlyStupidException => BadRequest("Another stupid exception!")
}

Es realmente importante manejar las excepciones generadas en Future s porque la mayoría de las veces son más insidiosas. Por lo general, no se ponen en su lugar porque se ejecutan en un contexto de ejecución y un hilo diferente, y por lo tanto no le piden que los corrija cuando suceden, especialmente si no nota nada en los registros o en el comportamiento de solicitud.

Usando las cláusulas try-catch

Además de las construcciones funcionales, como Try , Option y Either para el manejo de errores, Scala también admite una sintaxis similar a la de Java, utilizando una cláusula try-catch (con un bloque de potencial también). La cláusula catch es una coincidencia de patrón:

try { 
  // ... might throw exception
} catch {
  case ioe: IOException => ... // more specific cases first
  case e: Exception => ...
  // uncaught types will be thrown
} finally {
  // ...
}

Convertir excepciones en uno u otro tipo de opción

Para convertir excepciones en Either o Option tipos, puede utilizar métodos que proporcionan en scala.util.control.Exception

import scala.util.control.Exception._

val plain = "71a"
val optionInt: Option[Int] = catching(classOf[java.lang.NumberFormatException]) opt { plain.toInt }
val eitherInt = Either[Throwable, Int] = catching(classOf[java.lang.NumberFormatException]) either { plain.toInt }


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow