Attraper plusieurs exceptions à la fois dans Scala

comment attraper plusieurs exceptions à la fois dans Scala? Y a-t-il une meilleure façon que dans C#: attraper plusieurs exceptions à la fois?

57
demandé sur Community 2011-06-17 13:51:51

4 réponses

, Vous pouvez lier l'ensemble du modèle à une variable comme ceci:

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 Scala Langage de Spécification à la page 118, paragraphe 8.1.11 appelle le Motif des solutions de rechange.

Regarder Pattern Matching Unleashed pour approfondir le pattern matching in Scala.

130
répondu agilesteel 2018-06-17 09:03:42

comme vous avez accès à toutes les capacités de correspondance des motifs de scala dans la clause de capture, 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 les mêmes gestionnaires, encore et encore, vous pouvez créer votre propre structure de contrôle :

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

certaines de ces méthodes sont disponibles dans l'objet scala.util.contrôle.Exceptions . à défaut, failAsValue, la manipulation peut être juste ce dont vous avez besoin

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

malheureusement, avec cette solution, vous n'avez pas accès à l'exception où vous utilisez les modèles alternatifs. À ma connaissance, vous ne pouvez pas lier sur un modèle alternatif avec le cas e @ (_ : SqlException | _ : IOException) . Donc, si vous avez besoin d'accéder à l'exception, vous devez nid de rapprochement :

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")
}
28
répondu Didier Dupont 2011-06-17 13:45:04

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 précis peut-être pas le meilleur exemple pour illustrer comment vous pouvez l'utiliser, mais je le trouve assez utile dans de nombreuses occasions.

14
répondu Wilfred Springer 2012-02-29 19:46:06

c'était le seul moyen pour moi, qui est passé par le sbt clean coverage test coverageReport sans jeter l'exception de parsing désagréable ...

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
répondu Yordan Georgiev 2018-04-17 00:05:14