【问题标题】:Scala, ZIO - how to return custom error from ZIOScala,ZIO - 如何从 ZIO 返回自定义错误
【发布时间】:2022-12-01 00:52:58
【问题描述】:

我有一个使用tapirsttp.client3.json._的简单代码:

def method(...): Task[MyResponse] = 
   someLogic().response(asJson[MyResponse]).flatMap(res => ZIO.fromEither(res.body))

但现在我想在这里添加一些逻辑,以便在 asJson[MyResponse] 失败时使用自定义错误。 我创建了错误层次结构:

sealed trait MyError extends Throwable
case class MyFirstError (msg: String) extends MyError 
case class MySecondError (msg: String) extends MyError 

而且我将Task更改为IO[MyError, MyResponse],但我不知道当错误出现时我应该如何返回错误并在一切正常时返回相同的正确MyResponse。 我试过这样的:

def method(...): IO[MyError, MyResponse] = 
       someLogic().response(asJson[MyResponse]).flatMap{ res =>
         res.code match {
           case StatusCode.BadRequest => ZIO.fail(MyFristError("my error"))
           case StatusCode.Forbidden => ZIO.fail(MySecondError("my other error"))
           case _ => ZIO.fromEither(res.body).orDie
         }
       }

我在这里遇到错误Required IO[MyError, MyResponse], Found ZIO[Any, Throwable, MyResponse] 我应该如何修复此代码以返回我的自定义错误取决于状态代码并在一切正常时正确响应?

【问题讨论】:

  • 我认为这个 someLogic().response(asJson[MyResponse]) 已经将错误通道设置为 Throwable - 当您 flatMap 时,您计算之前的错误通道与 flatMap 中的错误通道之间的公共时间 Throwable。在flatMapping 响应之前,您必须从ThrowablemapErrorMyError(或死亡)。

标签: scala either zio tapir


【解决方案1】:

我认为你在“包罗万象”的情况下遇到了这个问题:

  case _ => ZIO.fromEither(res.body).orDie

fromEither 正在返回一些 IO[E, A] 我的假设是 E 是您遇到 Throwable 的地方。明确声明类型应该修复它:fromEither[MyError, MyResponse]

如果无法显式添加类型,则可以使用 refineOrDie { case e: MyError => e } 而不是使用 orDie

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2020-10-22
    • 2021-08-04
    • 2021-07-21
    • 2022-07-10
    相关资源
    最近更新 更多