Я хочу, чтобы следующий код возвращал пользовательское сообщение, когда один из методов, callfuture1()
или callfuture2()
, генерирует исключение. Мое понимание заключалось в том, что если какое-либо будущее не удастся, f
будет неудачным будущим.невозможно обработать исключение из будущего сбоя
Однако, когда callfuture1
выдает исключение. f.onFailure
не выполнен. Вместо этого я вижу, что стек вызовов остановлен в строке кода в callFuture1()
, где возникло исключение, и возвращается стандартное internalError. Почему это происходит?
val f = for {
x <- callfuture1()
y <- callfuture2()
} yield y
f.onFailure {
//send an internalserver error with some custom message
}
f.map {
//send data back
}
==== Обновление ====
я вижу из ответов, что потенциальная проблема в том, что исключение выбрасывает за пределами будущего и, следовательно, мой код не может его поймать, что не удалось будущее , Итак, я изменил код таким образом, что Исключение происходит только в будущем. Я все еще не могу объяснить поведение, которое вижу. (Интересно, если он должен что-нибудь сделать с рамкой Play.)
def controllerfunction(id: String) = Action.async{
val f = for{
x <- callfuture1(id)
y <- callfuture2(x)
} yield y
y.onFailure{case t =>
println("This gets printed");
Ok("shit happened, but i am still ok")}
y.map{resp:String => Ok(resp)}
}
def callfuture1(id: String):Future[Obj1] = {
for {
val1 <- callfuture1.1(id)
val2 <- callfuture1.2(val1)
} yield val2
}
def callfuture1.2:Future[Obj3] = Future{
thrown new Exception("TEST ME");
}
def callfuture 1.1:Future[Obj4] = {...}
def callfuture2: Future[String] = {....}
Expectation. Метод callfuture1.2 бросает исключение внутри будущего, так что мое ожидание OnFailure должно быть выполнено, (который не начал выполняться), и ответ вернулся должен «Дерьмо случилось, но я до сих пор нормально»
Актуальность Структура воспроизведения возвращает InternalServerError, и я вижу столбец ошибок на моей консоли. Я вижу, что printlin («Это печатается») выполняется.
Не могу понять, что происходит. Какие-нибудь идеи?
==== Обновление 2 =====
Я проверил, что проблема возникает только при вызове внутри контроллера рамки игры (я использую играть 2.5). Как автономная программа scala, все работает так, как ожидалось. Я считаю, что обработка ошибок воспроизведения захватывает исключительное исключение и печатает трассировку стека. Я думаю, что это должно происходить только в среде разработки.
Попробуйте 'val f1 = callfuture1(); val f2 = callfuture2; f = для {x <- f1; y <- f2} дают y'. Разница в том, что в вашем случае фьючерсы выполняются последовательно (y ждет завершения вызова future1). – chuwy
Что вы подразумеваете под «stack stop»? Что такое «стандартная внутренняя ошибка»? Откуда вы знаете, что 'onFailure' не выполняется? Какова фактическая ошибка? – Dima
Также. обратите внимание, что 'onFailure' может использоваться только для побочных эффектов. Он не может изменить исключение, содержащееся в «Будущем». Если вы хотите возиться с исключением, вам нужно использовать 'transform' или' recover' – Dima