webentwicklung-frage-antwort-db.com.de

Mehrere Ausnahmen gleichzeitig in Scala abfangen

Wie fange ich in Scala mehrere Ausnahmen gleichzeitig an? Gibt es einen besseren Weg als in C #: Mehrere Ausnahmen gleichzeitig einfangen?

63
TN.

Sie können das gesamte Muster wie folgt an eine Variable binden:

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)
}

Siehe die Scala-Sprachspezifikation Seite 118, Absatz 8.1.11 , die als Musteralternativen bezeichnet wird.

Watch Pattern Matching Unleashed für ein tieferes Eintauchen in Pattern Matching in Scala.

138
agilesteel

Da Sie in der catch-Klausel Zugriff auf die vollständigen Pattern-Matching-Funktionen von scala haben, können Sie eine Menge tun: 

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

Wenn Sie immer und immer wieder dieselben Handler schreiben müssen, können Sie dafür Ihre eigene Kontrollstruktur erstellen: 

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

Einige dieser Methoden sind in object scala.util.control.Exceptions verfügbar. Wenn dies fehlschlägt, ist die Handhabung möglicherweise genau das, was Sie brauchen

Edit: Im Gegensatz zu dem, was unten gesagt wird, können alternative Muster gebunden werden, so dass die vorgeschlagene Lösung unnötig komplex ist. Siehe @agilesteel-Lösung

Leider haben Sie mit dieser Lösung keinen Zugriff auf die Ausnahme, in der Sie die alternativen Muster verwenden. Meines Wissens können Sie sich mit case e @ (_ : SqlException | _ : IOException) nicht an ein alternatives Muster binden. Wenn Sie also Zugriff auf die Ausnahme benötigen, müssen Sie Matcher verschachteln: 

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

Sie können auch scala.util.control.Exception verwenden:

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

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

Dieses spezielle Beispiel ist vielleicht nicht das beste Beispiel, um zu zeigen, wie Sie es verwenden können, aber ich finde es in vielen Fällen sehr nützlich.

14

Dies war der einzige Weg für mich, der sbt clean coverage test coverageReport durchlief, ohne die pastende Ausnahmebedingung zu werfen ... 

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