Scala Akka流输出处理Either

gzszwxb4  于 2022-11-05  发布在  Scala
关注(0)|答案(1)|浏览(201)

我在使用akka http和Web Socket时遇到了一个问题。我有一个函数通过我的代码返回给我以下类型:

Flow[String, Either[RuntimeException, T], Any]

从该类型中,我必须使用以下类型退出:

Either[Unit, Flow[String, T, Any]]

大家能告诉我,如果流的输出部分是左(RuntimeException),而T是右手的话,如何回答Unit吗?
提前感谢您的帮助

htrmnn0y

htrmnn0y1#

问题可能在于:

  • Tapir预期返回给用户的错误是Either[Unit, Flow[String, T, Ant]](未提供错误代数-Unit-因此预期不会向用户返回任何错误信息)
  • OP业务逻辑提供FlowEither[RuntimeException, T]的协同工作
  • 如果在WebSocket处理过程中出现一些错误,则可以将其结果存储在T中(因此T必须在内部类似于Either或类似ADT)

因此端点要么在连接时从不失败,要么在失败时不向用户显示任何信息(因为Left T = Unit)。一旦连接,它就可以以T的形式返回错误作为WebSocket响应。
在这种情况下,整个流可以被包裹在Right(flow)中,并且一个障碍被计算出来。
然后,RuntimeException可以转换为T,并且第二个障碍将被击败。

def handleRequest(input: Input): Either[
  Unit, // Left(()) is failure but without any error information for users
  Flow[String, Either[RuntimeException, T], Any] // Right(flow) on success
] = ...

// implementation depends on T and is only possible if T can somehow store
// either success and failure result
val mapError: RuntimeException => T = ...

def tapirLogic(input: Input): Either[Unit, Flow[String, T, ]] = for {
  // if we should go Left on request handling this is the moment
  businessLogic <- handleRequest(input)
  // turns Either[RuntimeExeption, T] to T
  flow = businessLogic.map((_.fold(mapError, identity)))
} yield flow

如果T无法存储故障信息怎么办?如果它无法被编码,例如:

{ "success": "success response" }
{ "failure": "failure response" }

或类似的?
在这种情况下,您的API定义没有准备好对错误消息进行编码,您必须在业务逻辑定义中的RuntimeException结果上将这些错误消息发送给用户。在这种情况下,您可能不想发送任何内容-那么您可以使用一些Flow运算符,例如,flatMapConcat在右侧为单值,而在左侧为空流。但是如果你想把一些信息返回给用户,Tapir就必须知道如何编码,所以T必须以某种方式编码。也许你需要两个不同的T:在原始流中只对成功消息进行编码,在为Tapir转换流中对TRuntimeException消息进行编码下面类型告诉您如何使实现正确

相关问题