Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON Decoding Issue in ZIO with Order-Dependent Parsing Failure for ADT Containing Mixed Types #711

Closed
SHSongs opened this issue Jul 9, 2024 · 6 comments

Comments

@SHSongs
Copy link

SHSongs commented Jul 9, 2024

Description

JSON decoding bug occurs when attempting to parse parameters following a sealed trait with mixed types (case objects and a case class). The decoder fails to process any parameters that follow the ADT parameter unless the fields in the case class containing the ADT are reordered.

Steps to Reproduce:

  1. Define a sealed trait with mixed type implementations (case objects and a case class) and a discriminator.
  2. Implement a wrapper case class that includes this ADT as a parameter among other basic type parameters.
  3. Use ZIO JSON to derive codecs for both the ADT and wrapper class.
  4. Encode an instance of the wrapper class to JSON and decode it back to verify the integrity of all fields.

Minimal Code to Reproduce

import zio.schema.annotation.discriminatorName
import zio.*
import zio.json.*
import zio.schema.*

@discriminatorName("type")
sealed trait Content derives Schema

object Content {
  given JsonCodec[Content] = zio.schema.codec.JsonCodec.jsonCodec(Schema[Content])

  case object AAA extends Content
  case object BBB extends Content
  case class CCC(a: Int) extends Content
}

case class Wrapper(a: Int, c: Content, b: Boolean) derives Schema
// case class Wrapper(a: Int, b: Boolean, c: Content) derives Schema // decoding success with this order
object Wrapper {
  import Content.given

  given JsonCodec[Wrapper] = zio.schema.codec.JsonCodec.jsonCodec(Schema[Wrapper])
}

val v = Wrapper(a = 1, c = Content.AAA, b = true)
val str = v.toJson
println(s"Decoding from String: ${str.fromJson[Wrapper]}")

Expected Behavior:

The decoder should reconstruct the Wrapper instance correctly, preserving the order and integrity of fields (a, b, c)

Actual Behavior:

When the ADT field c is placed between two other fields, decoding fails for the fields that follow the ADT field. However, rearranging the fields in the Wrapper class (placing the ADT field at the end) resolves the issue.

Environment:

  • ZIO Schema: 1.2.2
  • ZIO JSON: 0.7.1
  • Scala: 3.4.2
@jdegoes
Copy link
Member

jdegoes commented Aug 1, 2024

/bounty $125

Copy link

algora-pbc bot commented Aug 1, 2024

💎 $125 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #711 with your implementation plan
  2. Submit work: Create a pull request including /claim #711 in the PR body to claim the bounty
  3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Thank you for contributing to zio/zio-schema!

Add a bountyShare on socials

Attempt Started (GMT+0) Solution
🔴 @michaelitindi Aug 5, 2024, 7:33:03 AM WIP
🟢 @guersam #710

@michaelitindi
Copy link

michaelitindi commented Aug 5, 2024

/attempt #711

@guersam
Copy link
Contributor

guersam commented Aug 6, 2024

It's already solved by #710 (scastie).

The reason why it failed to decode was the bug in empty object decoding rather than the order dependency.

On the contrary, there's a bug where the second Wrapper was being decoded successfully, because it means it didn't fully consume the input string. Related issue: #712

Copy link

algora-pbc bot commented Aug 6, 2024

💡 @guersam submitted a pull request that claims the bounty. You can visit your bounty board to reward.

Copy link

algora-pbc bot commented Aug 11, 2024

🎉🎈 @guersam has been awarded $125! 🎈🎊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants