Как «переопределить» исключение в scala?

поэтому у меня есть метод, в котором уже есть блок try, который выдает ExceptionA. Теперь мне нужно поместить еще один блок try, в котором вызывается этот метод, и он должен генерировать исключение с некоторыми дополнительными деталями. Что-то вроде этого:

method inner():
    try{
    //some logic
    } catch {
    throw new ExceptionA("exceptionA occurred")
    }

method outer():
    identifier = fromSomeDBCallPrivateToOuter()
    try{
    inner()
    } catch {
    // now either 
    // throw new Exception("Error with identifier" + identifier)
    // or
    // append identifier to thrown error from inner() 
    }

Может ли кто-нибудь дать какое-либо представление или предложение о том, как это сделать в Scala? Заранее спасибо!


35
2

Ответы:

Решено

То, что у вас есть в вашем фрагменте, будет работать так, как написано (если вы исправите синтаксис), с оговоркой, что исключения неизменяемы (и даже они не были, все равно не стоит их видоизменять), поэтому вместо " добавляя» к исключению, вам нужно создать новый и установить оригинал как cause.

Однако в scala более идиоматично использовать Try монады вместо «процедурных» try/catch блоков. Что-то вроде этого:

     case class ExceptionB(id: String, original: ExceptionA) 
         extends Exception(s"Badness happened with id $id", original)
     def outer(): Try[ReturnType] = 
       val id = getId()
       Try {
         inner 
       } recover { 
         case e: ExceptionA if iWannaNewException => throw new Exception(s"Id: id")
         case e: ExceptionA => throw ExceptionB(id, e)
      }

Вы также можете использовать Either структура. Эта структура может возвращать Right(value), если функция завершается без ошибок, или Left(message), содержащую информацию об ошибке. Вы можете адаптировать свой код, как показано ниже:

def inner(): Either[String, Int] = {
  if (checkSomeStuff()) Left("Cannot assigne identifier")
  else Right(doSomeStuff())
}

def outer(): Either[String, Int] = {
  inner() match {
    case Left(error)  => {
      println("There is an error: " + error) 
     // you can also throw new Exception(s"Some info about $error") here
    }
    case Right(identifier) => {
      println("Identifier : " + identifier) 
      doSomeStuffWithId()  // do some staff for id
    }
  }
}

Если вы хотите использовать исключения, вам нужно выбрать, кто будет обрабатывать случай ошибки (в функции inner или в функции outer).