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

Cannot generate schema for sealed trait with enum implementors #697

Closed
anqit opened this issue Jun 27, 2024 · 6 comments · Fixed by #707
Closed

Cannot generate schema for sealed trait with enum implementors #697

anqit opened this issue Jun 27, 2024 · 6 comments · Fixed by #707

Comments

@anqit
Copy link

anqit commented Jun 27, 2024

I'm trying to use zio-schema with zio-http to de/serialize request/response Bodys. I have a sealed trait representing the response body of my API, and two implementors of that trait, both of which are enums, representing success bodies (with a "data" field) and failure bodies (with a "message" field), but cannot seem to generate a schema for this structure. The below scala-cli script is a minimal representation of what I've tried. This compiles but fails at runtime with a ClassCastException:

//> using dep dev.zio::zio:2.1.1
//> using dep dev.zio::zio-http:3.0.0-RC8

import zio.schema.{ DeriveSchema, Schema, TypeId }
import zio.schema.Schema.Sequence
import zio.schema.codec.BinaryCodec
import zio.schema.codec.JsonCodec.schemaBasedBinaryCodec
import zio.http.*

sealed trait HttpResponse[+D]

enum HttpSuccessResponse[+D](val data: D) extends HttpResponse[D]:
   case Created[E](entity: E) extends HttpSuccessResponse[E](entity)
   case Found[E](entity: E) extends HttpSuccessResponse[E](entity)
   case Updated[E](entity: E) extends HttpSuccessResponse[E](entity)
   case Deleted[E](entity: E) extends HttpSuccessResponse[E](entity)
   case Succeeded[E](entity: E) extends HttpSuccessResponse[E](entity)

enum HttpFailureResponse(val message: String) extends HttpResponse[String]:
   case ServerError(msg: String) extends HttpFailureResponse(msg)
   case RequestError(msg: String) extends HttpFailureResponse(msg)

given HttpSuccessResponseSchema[D](using Schema[D]): Schema[HttpSuccessResponse[D]] = DeriveSchema.gen

given HttpFailureResponseSchema: Schema[HttpFailureResponse] = DeriveSchema.gen

given HttpResponseSchema[D](using Schema[D]): Schema[HttpResponse[D]] = DeriveSchema.gen

val response = HttpSuccessResponse.Created("user")

val body = Body.from(response)

@main def run() =
   println(body.asString)

The full error is

Exception in thread "main" java.lang.ExceptionInInitializerError
        at run.main(error_repro.scala:34)
Caused by: java.lang.ClassCastException: class zio.schema.Schema$CaseClass1$$anon$7 cannot be cast to class zio.schema.Schema$CaseClass0 (zio.schema.Schema$CaseClass1$$anon$7 and zio.schema.Schema$CaseClass0 are in unnamed module of loader 'app')
        at zio.schema.codec.JsonCodec$JsonEncoder$.$anonfun$2(JsonCodec.scala:388)
        at zio.Chunk$Arr.mapChunk(Chunk.scala:1769)
        at zio.ChunkLike.map(ChunkLike.scala:121)
        at zio.ChunkLike.map$(ChunkLike.scala:39)
        at zio.Chunk.map(Chunk.scala:42)
        at zio.schema.codec.JsonCodec$JsonEncoder$.enumEncoder(JsonCodec.scala:389)
        at zio.schema.codec.JsonCodec$JsonEncoder$.schemaEncoder(JsonCodec.scala:205)
        at zio.schema.codec.JsonCodec$JsonEncoder$.encode(JsonCodec.scala:177)
        at zio.schema.codec.JsonCodec$$anon$2.encode(JsonCodec.scala:93)
        at zio.schema.codec.JsonCodec$$anon$2.encode(JsonCodec.scala:92)
        at zio.http.Body$.from(Body.scala:209)
        at error_repro$package$.<clinit>(error_repro.scala:13)

Am I just doing this incorrectly or is this something not supported?

@anqit
Copy link
Author

anqit commented Jun 27, 2024

potentially related to #668 ?

@jdegoes
Copy link
Member

jdegoes commented Jun 28, 2024

/bounty $100

Copy link

algora-pbc bot commented Jun 28, 2024

💎 $100 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #697 with your implementation plan
  2. Submit work: Create a pull request including /claim #697 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
🟢 @pablf #707

@anqit
Copy link
Author

anqit commented Jun 30, 2024

I'm guessing an assigned bounty means that what I'm trying to do is indeed unsupported at this time? I was hoping I was just doing something wrong...

Copy link

algora-pbc bot commented Jun 30, 2024

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

Copy link

algora-pbc bot commented Jul 9, 2024

🎉🎈 @pablf has been awarded $100! 🎈🎊

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

Successfully merging a pull request may close this issue.

2 participants