Виловлювання кількох винятків одночасно в Scala


Відповіді:


165

Ви можете прив'язати весь шаблон до такої змінної:

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, що називається Альтернативами шаблонів.

Годинники Pattern Matching розв'язали для більш глибокого занурення в зіставленні з зразком в Scala.


який не проходить через sbt clean coverage test coverageReportчас написання ... github.com/scoverage/sbt-scoverage/issues/257
Йордан Георгієв

32

Оскільки ви маєте доступ до повноцінних можливостей збігу шаблонів 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 . 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")
}

Цікаво, я раніше не бачив альтернативних варіантів. Я думаю, що вони не охоплені PinS .
kassens

1
Прив'язка шаблону працює альтернативно, і особливо корисно в цьому випадку. Зв'язана змінна навіть отримує як тип найбільш специфічні загальні надтипи альтернатив. Вкладання учасників маршу непотрібне. Я підтримую вашу відповідь, якщо ви оновите її, сказавши так.
Жан-Філіп Пелле

@ Jean-Philippe: Відмінно !! Я намагався, перш ніж відповісти, і не зміг зробити це. Перевіряючи специфікацію, мабуть, занадто швидко, я думав, що це говорить те саме (на стор. 113 альтернативою є Pattern, і ви можете прив’язати лише Pattern3). Що таке синтаксис?
Дідьє Дюпон,

16

Ви також можете використовувати 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

Це був єдиний шлях для мене, який пройшов через 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.