Ответ 1
Я бы сказал, что чистым функциональным способом было бы использование типа, который может содержать допустимые и ошибки.
Для этого вы можете использовать Validation form scalaz
Но если вам не нужно больше, чем от scalaz (вы будете ^^), вы можете использовать очень простой материал, используя Promise[Either[String, Ingredient]]
в качестве результата и свой метод fold
в блоке Async. То есть map
, чтобы преобразовать значение, когда погашено обещание, и fold
на то, что искуплено.
Хорошая точка = > нет исключения = > всякая вещь напечатана check: -)
ИЗМЕНИТЬ
Это может потребоваться немного информации, вот два варианта: попробуйте поймать, благодаря @hheraud) и Либо. Не поставил Validation
, спросите меня, если потребуется. object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
//Using Try Catch
// What was missing was the wrapping of the BadRequest into a Promise since the Async
// is requiring such result. That done using Promise.pure
def test1 = Async {
try {
val created = Promise.pure(new {val name:String = "myname"})
created map { stuff =>
Redirect(routes.Application.index()).flashing("success" -> "Stuff '%s' show".format(stuff.name))
}
} catch {
case _ => {
Promise.pure(Redirect(routes.Application.index()).flashing("error" -> "an error occurred man"))
}
}
}
//Using Either (kind of Validation)
// on the Left side => a success value with a name
val success = Left(new {val name:String = "myname"})
// on the Right side the exception message (could be an Exception instance however => to keep the stack)
val fail = Right("Bang bang!")
// How to use that
// I simulate your service using Promise.pure that wraps the Either result
// so the return type of service should be Promise[Either[{val name:String}, String]] in this exemple
// Then while mapping (that is create a Promise around the convert content), we folds to create the right Result (Redirect in this case).
// the good point => completely compiled time checked ! and no wrapping with pure for the error case.
def test2(trySuccess:Boolean) = Async {
val created = Promise.pure(if (trySuccess) success else fail)
created map { stuff /* the either */ =>
stuff.fold(
/*success case*/s => Redirect(routes.Application.index()).flashing("success" -> "Stuff '%s' show".format(s.name)),
/*the error case*/f => Redirect(routes.Application.index()).flashing("error" -> f)
)
}
}
}