在 Scala 中一次捕获多个异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6384073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:06:15  来源:igfitidea点击:

Catching multiple exceptions at once in Scala

exceptionscalaexception-handlingpattern-matchingtry-catch

提问by TN.

How to catch multiple exceptions at once in Scala? Is there a better way than in C#: Catch multiple exceptions at once?

如何在 Scala 中一次捕获多个异常?有没有比 C# 更好的方法:一次捕获多个异常?

回答by agilesteel

You can bind the whole pattern to a variable like this:

您可以将整个模式绑定到一个变量,如下所示:

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

See the Scala Language Specification page 118 paragraph 8.1.11called Pattern alternatives.

请参阅Scala 语言规范第 118 页第 8.1.11 段,称为模式替代。

Watch Pattern Matching Unleashedfor a deeper dive into pattern matching in Scala.

观看Pattern Matching Unleashed以更深入地了解 Scala 中的模式匹配。

回答by Didier Dupont

As you have access to the full pattern matching capabilities of scala in the catch clause, you can do a lot :

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

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

Note that if you need to write the same handlers time and time again you can create your own control structure for that :

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

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

Some such methods are available in object scala.util.control.Exceptions. failing, failAsValue, handling may be just what you need

对象scala.util.control.Exceptions中提供了一些此类方法。失败,failAsValue,处理可能正是您所需要的

Edit : Contrary to what is said below, alternative patterns can be bound, so the proposed solution is needlessly complex. See @agilesteel solution

编辑:与下面所说的相反,可以绑定替代模式,因此建议的解决方案不必要地复杂。请参阅@agilesteel 解决方案

Unfortunately, with this solution, you have no access to the exception where you use the alternative patterns. To my knowledge, you cannot bind on an alternative pattern with case e @ (_ : SqlException | _ : IOException). So if you need access to the exception, you have to nest matchers :

不幸的是,使用此解决方案,您无法访问使用替代模式的异常。据我所知,您不能使用 case 绑定替代模式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")
}

回答by Wilfred Springer

You can also use scala.util.control.Exception:

您还可以使用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") 
}

This specific example might not be the best example to illustrate how you can use it, but I find it pretty useful in many occasions.

这个具体的例子可能不是说明如何使用它的最佳例子,但我发现它在很多情况下都非常有用。

回答by Yordan Georgiev

This was the only way for me, which passed trough the sbt clean coverage test coverageReportwithout throwing the nasty parsing exception ...

这对我来说是唯一的方法,它通过了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)