当前位置: 首页 > 知识库问答 >
问题:

将多个WS-Call组合为一个结果时的错误处理

袁河
2023-03-14

我正在同时学习scala、play和web服务,所以请耐心等待。我建立了一个小型聚合器服务,它将天气web服务与google的地理编码和places web服务相结合。我有些工作要做,但我对处理错误的正确方法有点困惑。(我把代码贴在了邮件的末尾。)

所以api使用lat/long的地方,所以我使用地理代码api从邮政编码中获取lat/long。在处理对地理代码api的调用的响应时,我最终会得到一个(Option[String], Option[String])(保存在maybeLocval中)。在检查maybeLoc的匹配语句中,如果它最终是(无,无),我返回Promise(),因为我需要从平面图调用返回Promise

对此我有两个问题:

1.)在这些平面地图或地图调用中的一个中,处理无法进行任何进一步处理的情况的正确方法是什么?它要求我返回一个promise,但是创建一个空的Promise,当我去兑换时它会超时,这似乎是一个非常糟糕的主意。

2.) 我假设对 Promise() 的调用会创建一个空的 promise 对象,在尝试赎回它时总是会超时,我是对的吗?我无法从scaladoc中真正分辨出来,也无法从Google中找到任何有关它的信息。

我希望我的问题对你有意义,并且足够清楚。代码如下:

def bothAsJson(zipcode:String) = Action {
    val promiseOfLoc = Geocode.buildUrlFor(zipcode).get()
    val promiseOfWeather = Weather.buildUrlFor(zipcode, "json").get()

    val result = promiseOfLoc.flatMap { locResp => 
        val maybeLoc = Geocode.extractLocation(locResp.body.toString())
        maybeLoc match {
            case (Some(lat), Some(lng)) => {
                val promiseOfPlaces = Places.buildUrlFor(lat,lng).get()
                promiseOfPlaces.flatMap { placesResp =>
                    promiseOfWeather.map { weatherResp =>
                        (weatherResp.body.toString(), placesResp.body.toString())
                    }
                }
            }
            case _ => Promise()
        }
    }

    Async {
        result.orTimeout("Timeout!", 2000).map {response =>
            response.fold(
                result => Ok("Got:\n\nweather:\n" + result._1 + "\n\nplaces:\n" + result._2),
                timeout => InternalServerError(timeout)
            )
        }
    }
}

共有1个答案

夏俊杰
2023-03-14

如果您得到(无,无),您不应该寻求超时,而是返回另一条我相信的错误消息。我在下面提供了一个示例。

我想你需要scalaz 7的OptionT。我会这样写:

import scalaz._
import Scalaz._

def bothAsJson(zipcode:String) = Action {
    val promiseOfLoc = Geocode.buildUrlFor(zipcode).get.map { Option(_.body.toString()) }
    val promiseOfWeather = Weather.buildUrlFor(zipcode, "json").get
       .map{ lockResp => 
           val (lat,lng) = Geocode.extractLocation(locResp.body.toString())
           (lat |@| lng).tupled
       }
    def buildPlaces(lat: String, lng: String) = Places.buildUrlFor(lat,lng).get
       .map { Option(_.body.toString) }

    val result = (for {
       (lat, lng) <- OptionT(promiseOfLoc)
       places     <- OptionT(Places.buildUrlFor(lat,lng).get())
       weather    <- OptionT(promiseOfWeather)
    } yield (places, weather)).run

    Async {
        result.orTimeout("Timeout!", 2000).map {response =>
            response.fold(
                result => {
                  result.map(
                   some => Ok("Got:\n\nweather:\n" + some._1 + "\n\nplaces:\n" + some._2)
                  ).getOrElse(BadRequest("lat/lng failed probably?"))
                },
                timeout => InternalServerError(timeout)
            )
        }
    }
}

使用< code>OptionT,我们可以将flatMap视为< code >选项,如果得到None,就可以不处理任何内容。最后,我们得到了一个< code>Promise[Option[T]],这是一个很好的例子。另一个处理错误的好方法是用同样的方法使用/EtherT。

|@|是一个应用生成器。它需要2个选项,如果双方都是一些,则返回一个Option((Int, Int))。如果一方或双方都是,则返回

注意:要实现这一点,您需要一个scalazMonad[Promise]实例

implicit val PromiseInstance = new Monad[Promise] {
  // override def map[A,B](fa: Promise[A])(f: A => B) = fa.map(f)
  def point[A](a: => A) = Promise.pure(a)
  def bind[A,B](fa: Promise[A])(f: A => Promise[B]) = fa.flatMap(f)
}

另外请注意,我已经在SO编辑器中编写了所有这些代码,可能缺少大括号。但所有代码都应该或多或少正确,我在repl中测试了其中的部分内容。

请随时在freenode irc上#scalaz或scalaz google组上寻求帮助。

 类似资料:
  • 本文向大家介绍MongoDB聚合分组多个结果,包括了MongoDB聚合分组多个结果的使用技巧和注意事项,需要的朋友参考一下 要聚合多个结果,请在MongoDB中使用$group。让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是汇总组多个结果的查询- 这将产生以下输出-

  • 我有索引,其中每个文档都有这样的结构: 我需要计算每个演员对应的电影数量(演员可以在actor_1_name、actor_2_name或actor_3_name字段中) 这3个字段的映射是: 有没有一种方法,我可以聚合的结果,可以结合所有3个演员领域的条款,并给出一个单一的聚合。 目前,我正在为每个actor字段创建单独的聚合,并通过我的JAVA代码将这些不同的聚合合并成一个。 通过创建不同的聚合

  • 我的表是: 我有一个包含10,000个地址的列表,如果地址存在于表中,我将循环访问该列表以检索相应的纬度/经度。 查询如下所示: 然后我检查结果集,看看是否有匹配。然后通过上面的查询循环其他9,999个地址,这花费的时间太长了。 是否有一种方法可以创建一个包含所有10000个地址的查询,并返回一个包含4列的结果集: 任何未找到地址在结果集列中都应该有一个空(0或null)纬度/经度值。我假设我可以

  • 在mongodb聚合调用中,如何使用$group操作符将管道中的所有文档分组为一个结果? 假设我有一组记录,看起来像这样: 我想使用聚合函数在数据库中查询在给定日期范围内注册的用户列表,并将其作为列表返回。我想要一个如下的结果: 我的查询如下所示: 到目前为止,一切顺利。我现在有一部分记录,所有记录的注册日期都在所需的范围内。但这就是我遇到麻烦的地方。现在,我想将所有这些记录分组到一个包含所有ID

  • 问题内容: 我是新手,发现错误处理非常冗长。我已经读过它的理由并大体上同意,但是似乎在某些地方似乎有更多代码来处理错误而不是实际工作。这是一个(人为的)示例,我在其中传送“ Hello world!”。进入cat并读取并打印输出。基本上,每一行都可以再处理三个错误,而我什至没有处理任何事情。 有没有惯用的,干净的方法来处理此问题?我只是觉得我在想什么。 问题答案: 显然,我们必须处理任何错误。我们

  • execute方法不仅可以执行单条查询语句,而且还可以执行多条查询语句,不同查询语句之间用分号(;)隔开。在给出例子之前,先使用如下SQL建立一个图书销售表t_booksale,并向其中插入三条记录。 建立t_booksale表 DROP TABLE IF EXISTS mydb.t_booksale; CREATE TABLE mydb.t_booksale ( id int(10)