web-dev-qa-db-fra.com

Attraper plusieurs exceptions à la fois dans Scala

Comment intercepter plusieurs exceptions à la fois dans Scala? Y at-il une meilleure façon que dans C #: attraper plusieurs exceptions à la fois?

63
TN.

Vous pouvez lier le motif entier à une variable comme celle-ci:

try {
   throw new Java.io.IOException("no such file")
} catch {
   // prints out "Java.io.IOException: no such file"
   case e @ (_ : RuntimeException | _ : Java.io.IOException) => println(e)
}

Voir la Spécification du langage Scala page 118, paragraphe 8.1.11 appelé Modèles alternatifs.

Watch Pattern Matching Unleashed pour une plongée plus en profondeur dans la recherche de motifs dans Scala.

138
agilesteel

Comme vous avez accès aux capacités complètes de correspondance de modèle de scala dans la clause catch, vous pouvez faire beaucoup: 

try {
  throw new IOException("no such file")
} catch {
  case _ : SQLException | _ : IOException => println("Resource failure")
  case e => println("Other failure");
}

Notez que si vous avez besoin d'écrire à maintes reprises les mêmes gestionnaires, vous pouvez créer votre propre structure de contrôle pour cela: 

def onFilesAndDb(code: => Unit) { 
  try { 
    code 
  } catch {
    your handling code 
  }
}

Certaines de ces méthodes sont disponibles dans l'objet scala.util.control.Exceptions . en cas d'échec, failAsValue, le traitement peut être exactement ce dont vous avez besoin

Edit: Contrairement à ce qui est dit ci-dessous, d’autres modèles peuvent être liés, ce qui rend la solution proposée inutilement complexe. Voir la solution @agilesteel

Malheureusement, avec cette solution, vous n’avez pas accès à l’exception dans laquelle vous utilisez les modèles alternatifs. À ma connaissance, vous ne pouvez pas utiliser un modèle alternatif avec case e @ (_ : SqlException | _ : IOException). Donc, si vous avez besoin d'accéder à l'exception, vous devez imbriquer les correspondants: 

try {
  throw new RuntimeException("be careful")
} catch  {
  case e : RuntimeException => e match {
    case _ : NullPointerException | _ : IllegalArgumentException => 
      println("Basic exception " + e)
    case a: IndexOutOfBoundsException => 
      println("Arrray access " + a)
    case _ => println("Less common exception " + e)
  }
  case _ => println("Not a runtime exception")
}
29
Didier Dupont

Vous pouvez également utiliser scala.util.control.Exception:

import scala.util.control.Exception._
import Java.io.IOException

handling(classOf[RuntimeException], classOf[IOException]) by println apply { 
  throw new IOException("foo") 
}

Cet exemple spécifique n'est peut-être pas le meilleur exemple pour illustrer comment vous pouvez l'utiliser, mais je le trouve plutôt utile dans de nombreuses occasions.

14
Wilfred Springer

C’était le seul moyen pour moi, qui passait par le sbt clean coverage test coverageReport sans lancer l’extrême analyse syntaxique… 

try {
   throw new CustomValidationException1( 
      CustomErrorCodeEnum.STUDIP_FAIL,
      "could be throw new CustomValidationException2")
    } catch {
    case e
      if (e.isInstanceOf[CustomValidationException1] || e
      .isInstanceOf[CustomValidationException2]) => {
        // run a common handling for the both custom exceptions
        println(e.getMessage)
        println(e.errorCode.toString) // an example of common behaviour 
    }
    case e: Exception => {
      println("Unknown error occurred while reading files!!!")
      println(e.getMessage)
      // obs not errorCode available ...
    }
}

    // ... 
    class CustomValidationException1(val errorCode: CustomErrorCodeEnum, val message: String)
    class CustomValidationException2(val errorCode: CustomErrorCodeEnum, val message: String)
0
Yordan Georgiev