Поймать несколько исключений одновременно в Scala - PullRequest
67 голосов
/ 17 июня 2011

Как отловить сразу несколько исключений в Scala?Есть ли лучший способ, чем в C #: Поймать несколько исключений одновременно?

Ответы [ 4 ]

146 голосов
/ 17 июня 2011

Вы можете привязать весь шаблон к переменной следующим образом:

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 , который называется Альтернативы шаблонов.

Часы Сопоставление с образцом Unleashed для более глубокого погружения в сопоставление с образцом в Scala.

30 голосов
/ 17 июня 2011

Поскольку у вас есть доступ к полным возможностям сопоставления с образцом scala в предложении catch, вы можете многое:

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 .fails, 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")
}
15 голосов
/ 29 февраля 2012

Вы также можете использовать 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") 
}

Этот конкретный пример может быть не лучшим примером, чтобы проиллюстрировать, как вы можете его использовать, но я считаю его довольно полезным во многих случаях.

0 голосов
/ 17 апреля 2018

Это был единственный путь для меня, который прошел через 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)
...