在scala中一次捕获多个异常

Catching multiple exceptions at once in Scala

如何在scala中同时捕获多个异常?是否有比C中更好的方法:一次捕获多个异常?


您可以将整个模式绑定到这样的变量:

1
2
3
4
5
6
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)
}

参见scala语言规范第118页第8.1.11段"模式备选方案"。

观看模式匹配释放更深入的模式匹配在scala。


由于您可以在catch子句中访问scala的完整模式匹配功能,因此可以做很多工作:

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

请注意,如果您需要一次又一次地编写相同的处理程序,您可以为此创建自己的控制结构:

1
2
3
4
5
6
7
def onFilesAndDb(code: => Unit) {
  try {
    code
  } catch {
    your handling code
  }
}

对象scala.util.control.exceptions中提供了一些这样的方法。失败、失败、失败、处理可能正是您所需要的。

编辑:与下面所说的相反,可以绑定可选模式,因此所建议的解决方案是不必要的复杂。见@agilesteel解决方案

不幸的是,使用此解决方案,您无法访问使用替代模式的异常。据我所知,你不能用案例e @ (_ : SqlException | _ : IOException)来约束另一种模式。因此,如果需要访问异常,则必须嵌套匹配器:

1
2
3
4
5
6
7
8
9
10
11
12
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")
}


您也可以使用scala.util.control.Exception

1
2
3
4
5
6
import scala.util.control.Exception._
import java.io.IOException

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

这个特定的示例可能不是说明如何使用它的最佳示例,但我发现它在许多情况下非常有用。


这是我唯一通过sbt clean coverage test coverageReport的方法,没有抛出令人讨厌的解析异常…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)