使用 scala 和 spray 产生错误
Produce an error with scala and spray
我尝试使用 scala 和 spray-routing 创建简单的 CRUD 应用程序。我有以下路线:
override def receive = runRoute {
path("entities" / LongNumber) { id =>
get {
produce(instanceOf[MyEntity]) {
func => ctx => heavyLookupById(id, func)
}
}
}
我是根据官方文档写的http://spray.io/documentation/1.2.2/spray-routing/marshalling-directives/produce/
MyEntity 如下(真的无关紧要):
case class MyEntity(text: String, id: Option[Long])
我有以下 json-支持对象
object MyJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
implicit val format = jsonFormat2(MyEntity)
}
"heavyLookupById" 函数包含一些繁重的阻塞计算(假设数据库查询或 http 请求),因此我必须处理 scala future:
def heavyLookupById(id: Long, func: MyEntity => Unit) = {
// ... heavy computations
future onSuccess { case x => func(x) }
}
但是如果我的未来失败了怎么办?我想响应错误请求 (400) 或未找到 (404) HTTP 错误,但该怎么做?如果我不在 "heavyLookupById" 中调用 "func" - 请求只是挂起 - 我相信它会因默认服务器超时(1 分钟左右)而失败。
您拥有 RequestContext (ctx),因此您可以调用 reject、failWith 或 RequestContext
上可用的任何其他方法。
val route = path("entities" / LongNumber) { id =>
get {
produce(instanceOf[MyEntity]) {
func => ctx => heavyLookupById(id, func, ctx)
}
}
}
def heavyLookupById(id: Long, func: MyEntity => Unit, ctx: RequestContext) = {
// ... heavy computations
val future = Future.successful(MyEntity("Hello", Some(1)))
future.onComplete {
case Success(value) => func(value)
case Failure(ex) => ctx.failWith(ex)
}
}
个人更喜欢handleWith而不是制作,我觉得它更容易阅读。
此外,在失败的情况下,喷雾只会 return 500,您可以使用 exceptionHandlers 进行自定义。
def heavyLookupById(id: Long) = {
// ... heavy computations
Future.successful(MyEntity("Hello", Some(1)))
}
val route = path("entities" / LongNumber) { id =>
get {
handleWith(heavyLookupById)
}
}
我尝试使用 scala 和 spray-routing 创建简单的 CRUD 应用程序。我有以下路线:
override def receive = runRoute {
path("entities" / LongNumber) { id =>
get {
produce(instanceOf[MyEntity]) {
func => ctx => heavyLookupById(id, func)
}
}
}
我是根据官方文档写的http://spray.io/documentation/1.2.2/spray-routing/marshalling-directives/produce/
MyEntity 如下(真的无关紧要):
case class MyEntity(text: String, id: Option[Long])
我有以下 json-支持对象
object MyJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
implicit val format = jsonFormat2(MyEntity)
}
"heavyLookupById" 函数包含一些繁重的阻塞计算(假设数据库查询或 http 请求),因此我必须处理 scala future:
def heavyLookupById(id: Long, func: MyEntity => Unit) = {
// ... heavy computations
future onSuccess { case x => func(x) }
}
但是如果我的未来失败了怎么办?我想响应错误请求 (400) 或未找到 (404) HTTP 错误,但该怎么做?如果我不在 "heavyLookupById" 中调用 "func" - 请求只是挂起 - 我相信它会因默认服务器超时(1 分钟左右)而失败。
您拥有 RequestContext (ctx),因此您可以调用 reject、failWith 或 RequestContext
上可用的任何其他方法。
val route = path("entities" / LongNumber) { id =>
get {
produce(instanceOf[MyEntity]) {
func => ctx => heavyLookupById(id, func, ctx)
}
}
}
def heavyLookupById(id: Long, func: MyEntity => Unit, ctx: RequestContext) = {
// ... heavy computations
val future = Future.successful(MyEntity("Hello", Some(1)))
future.onComplete {
case Success(value) => func(value)
case Failure(ex) => ctx.failWith(ex)
}
}
个人更喜欢handleWith而不是制作,我觉得它更容易阅读。
此外,在失败的情况下,喷雾只会 return 500,您可以使用 exceptionHandlers 进行自定义。
def heavyLookupById(id: Long) = {
// ... heavy computations
Future.successful(MyEntity("Hello", Some(1)))
}
val route = path("entities" / LongNumber) { id =>
get {
handleWith(heavyLookupById)
}
}