You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZIO Json:反序列化含密封特质的Tickers结构时Fiber失败,提示预期'{'却得到'['

解决Scala JSON反序列化中的结构不匹配与密封特质解码问题

一、先解决当前的直接错误:JSON结构不匹配

你遇到的Assertion failed: Fiber failed. A checked error was not handled. .data(expected '{' got '[')错误,本质是JSON输入结构和你定义的Tickers类不匹配:

  • Tickers是包含data: Seq[CexPair]的case class,对应的JSON应该是一个外层对象,示例格式如下:
    {
      "data": [
        {"timestamp": "2024-01-01", "bid": 1.23, "ask": 1.24},
        {"timestamp": "2024-01-02"}
      ]
    }
    
  • 但你的实际输入大概率是直接的JSON数组(没有外层data对象包裹),比如:
    [
      {"timestamp": "2024-01-01", "bid": 1.23, "ask": 1.24},
      {"timestamp": "2024-01-02"}
    ]
    

针对这个问题,你可以根据实际输入选择两种修正方向:

  1. 如果输入确实是带data字段的对象:
    • 检查输入JSON是否符合外层对象格式,确保没有语法错误(比如遗漏外层{})。
  2. 如果输入就是直接的数组:
    • 你当前定义的decoderPairs基于decoderTickers映射data字段,会先尝试把输入解析成Tickers对象,自然会因输入是数组报错。你需要直接定义数组解码器:
      implicit val decoderPairs: JsonDecoder[Seq[CexPair]] = JsonDecoder.seq(decoderCexPair)
      

二、密封特质CexPair的反序列化注意事项(潜在问题)

虽然当前错误不是密封特质导致的,但如果不处理好子类区分逻辑,后续反序列化CexPair子类时会出现异常:
自动生成的DeriveJsonDecoder.gen对于密封特质的子类,需要明确标识来判断实例化哪个子类。你可以通过两种方式解决:

1. 使用鉴别器字段(推荐)

以zio-json为例,可以给密封特质的解码器添加一个鉴别器字段(比如type),让JSON里的每个对象都带上子类标识:

implicit val decoderCexPair: JsonDecoder[CexPair] = 
  DeriveJsonDecoder.gen[CexPair].withDiscriminator("type")

对应的JSON对象需要包含子类标识:

{"type": "CexPairWithBidAsk", "timestamp": "2024-01-01", "bid": 1.23, "ask": 1.24}

或

{"type": "CexPairWithoutBidAsk", "timestamp": "2024-01-02"}

2. 手动编写解码器(基于字段存在性判断)

如果你的JSON里没有鉴别器字段,可以通过检查特定字段(比如bid/ask)是否存在来区分子类:

implicit val decoderCexPair: JsonDecoder[CexPair] = JsonDecoder.instance { cursor =>
  // 尝试获取bid字段,失败则判定为无bid/ask的子类
  cursor.get[Double]("bid").fold(
    _ => cursor.as[CexPairWithoutBidAsk],
    _ => cursor.as[CexPairWithBidAsk]
  )
}

总结

  1. 先确认JSON输入结构,修正解码器与输入的匹配问题,解决当前的expected '{' got '['错误;
  2. 完善密封特质CexPair的解码器逻辑,确保能正确区分两个子类。

内容的提问来源于stack exchange,提问作者Aarkon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:53:18