web-dev-qa-db-ja.com

Scalaで複数の例外を一度にキャッチする

Scalaで複数の例外を一度にキャッチする方法は? C#よりも良い方法はありますか? 一度に複数の例外をキャッチしますか?

67
TN.

次のように、パターン全体を変数にバインドできます。

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

the Scala Language Specification page 118パラグラフ8.1.11 パターンの代替案と呼ばれる。

Pattern Matching Unleashed を見て、Scalaでのパターンマッチングの詳細を確認してください。

149
agilesteel

Catch句のscalaの完全なパターンマッチング機能にアクセスできるため、多くのことができます。

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

同じハンドラを何度も記述する必要がある場合は、そのための独自の制御構造を作成できることに注意してください。

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

そのようなメソッドのいくつかは、オブジェクト scala.util.control.Exceptions で利用できます。 failing、failAsValue、処理は必要なものだけかもしれません

編集:以下で述べたこととは異なり、代替パターンをバインドできるため、提案されたソリューションは不必要に複雑になります。 @agilesteelソリューションを参照してください

残念ながら、このソリューションでは、代替パターンを使用する例外にアクセスできません。私の知る限り、ケースe @ (_ : SqlException | _ : IOException)を使用して代替パターンをバインドすることはできません。したがって、例外にアクセスする必要がある場合は、マッチャーをネストする必要があります。

_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")
}
_
30
Didier Dupont

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

この特定の例は、それをどのように使用できるかを示す最良の例ではないかもしれませんが、多くの場合に非常に役立つと思います。

15

これは私にとって唯一の方法で、厄介な解析例外をスローすることなくsbt clean coverage test coverageReportを通過しました...

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