因此端点要么在连接时从不失败,要么在失败时不向用户显示任何信息(因为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
1条答案
按热度按时间htrmnn0y1#
问题可能在于:
Either[Unit, Flow[String, T, Ant]]
(未提供错误代数-Unit
-因此预期不会向用户返回任何错误信息)Flow
与Either[RuntimeException, T]
的协同工作T
中(因此T
必须在内部类似于Either或类似ADT)因此端点要么在连接时从不失败,要么在失败时不向用户显示任何信息(因为Left T = Unit)。一旦连接,它就可以以
T
的形式返回错误作为WebSocket响应。在这种情况下,整个流可以被包裹在
Right(flow)
中,并且一个障碍被计算出来。然后,
RuntimeException
可以转换为T
,并且第二个障碍将被击败。如果
T
无法存储故障信息怎么办?如果它无法被编码,例如:或类似的?
在这种情况下,您的API定义没有准备好对错误消息进行编码,您必须在业务逻辑定义中的
RuntimeException
结果上将这些错误消息发送给用户。在这种情况下,您可能不想发送任何内容-那么您可以使用一些Flow
运算符,例如,flatMapConcat
在右侧为单值,而在左侧为空流。但是如果你想把一些信息返回给用户,Tapir就必须知道如何编码,所以T
必须以某种方式编码。也许你需要两个不同的T
:在原始流中只对成功消息进行编码,在为Tapir转换流中对T
和RuntimeException
消息进行编码下面类型告诉您如何使实现正确