在Akka流-Scala中抛出异常的最佳实践是什么?

在Akka流-Scala中抛出异常的最佳实践是什么?,scala,akka,akka-stream,Scala,Akka,Akka Stream,我是Akka Stream的新手,正在尝试找出处理流中意外行为的最佳实践 我正在构建一个流,用于将短期代码交换到长寿命访问令牌 以下是构建流的相关代码: override def ExchangeCode: Flow[String, AccessTokenInfo, NotUsed] = Flow[String].mapAsync(1) { code => ws.url(buildUrl("access_token")) .withQueryString( "gra

我是Akka Stream的新手,正在尝试找出处理流中意外行为的最佳实践

我正在构建一个流,用于将短期代码交换到长寿命访问令牌

以下是构建流的相关代码:

override def ExchangeCode: Flow[String, AccessTokenInfo, NotUsed] =
Flow[String].mapAsync(1) { code =>
  ws.url(buildUrl("access_token"))
    .withQueryString(
      "grant_type" -> "authorization_code",
      "code" -> code,
      "access_token" -> appToken
    )
    .withRequestTimeout(timeout)
    .get
    .map { response =>
      if (response.status != 200) throw new RuntimeException("Unexpected response")
      else response.json
    }
    .map { json =>
      AccessTokenInfo("123456", 123, "123456")
    }
}

我想知道如果状态代码不是200,抛出异常是否是正确的处理方法,但据我所知,这是提前终止流的唯一方法。(当前返回值是一个伪值)

如果状态不是200,为什么流必须终止?通常,您甚至希望将故障发送到下游,以便可以通知
流的任何用户并相应地采取行动

处理此类故障的典型方法是使用。稍微修改您的流程:

//                                  Add Try Output
//                                       |
//                                       v
override def ExchangeCode: Flow[String, Try[AccessTokenInfo], _] = 
  Flow[String] 
    ...
    .map { response => response.status match {
        case 200 => Try { response.json }
        case _   => Try { throw new RuntimeException("Unexpected Response") }
      }
    }
    .map( _ map (json => AccessTokenInfo("123456", 123, "123456")))
现在,如果可以检索或获取异常,并且能够处理故障情况,那么流的任何用户都可以获得有效的访问令牌

只有一种故障类型时的选项

在问题的特定用例中,
Try
似乎根本没有必要。由于只有1个异常可以由1个异常生成,因此
选项似乎更好:

override def ExchangeCode: Flow[String, Option[AccessTokenInfo], _] = 
  ...
        case 200 => Some(response.json)
        case _   => None
  ...