2016-06-21 2 views
1

мне нужно написать код, который должен попытаться сделать 2 действия:Агрегирование несколько ошибок

def foo(): Unit { 
    a() 
    b() 
} 

a() может бросить ошибку, и я все еще хочу b() произойти (может быть решена быть простой попытке поймать наконец-то) вещь заключается в том, что b() также может потерпеть неудачу, и я хотел бы вернуть какое-то обобщенное исключение из описания того и другого, что это лучший способ его реализовать?

+1

Если и б может потерпеть неудачу, но вы хотите, чтобы обработать их, даже в ситуации неудачи почему бы не использовать Try (а) .map (б) .collect (результат) или что-то? Композиция Монад всегда должна быть способ пойти. Если вам не нужна композиция, попробуйте (a) .recover (w/e) Попробуйте (b) .recover (w/e). Я могу предоставить более полный ответ, если вы хотите –

ответ

3

Возможно, вы знаете Option с его подклассами Some и None. Option отражает идею о том, что результат некоторой операции может быть пустым.

Аналогичным образом, Scala имеет Try с его подклассами Success и Failure, чтобы зафиксировать эффект отбрасывания функций исключениями. Вы можете обернуть вызовы a и b в Try объектах, которые затем можно манипулировать с помощью методов, доступных в классе Try. Например:

import scala.util.{Try, Success, Failure} 

def getExceptionMessage[U](t: Try[U]): Option[String] = t match { 
    case Success(_) => None 
    case Failure(x) => Some(x.getMessage) 
} 

def foo(): Unit = { 
    // If a() throws an exception, aa will become a Failure, otherwise a Success 
    val aa = Try(a()) 
    val bb = Try(b()) 

    val errors = List(getExceptionMessage(aa), getExceptionMessage(bb)).flatten 
    if (!errors.isEmpty) throw new Exception(errors.toString) 
} 
2

Легко и приятно:

val exc = List(Try(a), Try(b)) collect { case Failure(ex) => ex } 

Вы получите список (потенциально пустое) Throwable в качестве результата.