Spinoco / fs2-http

Http Server and client using fs2
MIT License
135 stars 26 forks source link

JSON content type not being turned into a String #34

Closed s5bug closed 5 years ago

s5bug commented 5 years ago
Could not get a string body: Media Type must be text, but is DefaultMediaType(application,json,true,true,WrappedArray(json))
    at org.discordscala.core.util.RequestUtil$.$anonfun$stringBodyFromResponse$2(RequestUtil.scala:64)
    at cats.syntax.EitherOps$.leftMap$extension(either.scala:144)
    at org.discordscala.core.util.RequestUtil$.$anonfun$stringBodyFromResponse$1(RequestUtil.scala:64)

RequestUtil.scala:64

pchlupacek commented 5 years ago

@sorenbug I will need to see your exact code, but my guess is that this is going on - You try to convert to string first and then trying to json. Default implementation of encoders/decoders is fairly strict, so if you read text, mime must be text and not json.

To fix this, you shall write simple decoder, which will be in your case a very simple one-two liner. You will use your serialization instance implicit( I think you mentioned you using circe) and essentially create and implciti saying `always when I have circe available for the type, I also have deserializer in fs2http, that requires application/json type and de/serializes the content).

From the examples in tests and current implementation of the decoder it shall be straightforward implementation in your case.

s5bug commented 5 years ago

Should I take a look at fs2-http-circe?

pchlupacek commented 5 years ago

@sorenbug from the first look I had on fs2-http-circe, yes, this is what you need to do.

s5bug commented 5 years ago

I ended up (since it was only visible to one method) just making an unbounded String decoder.

implicit val sd: BodyDecoder[String] = (bytes: ByteVector, contentType: ContentType) => {
  MIMECharset.asJavaCharset(util.getCharset(contentType).getOrElse(MIMECharset.`UTF-8`)).flatMap { implicit chs =>
    Attempt.fromEither(
      bytes.decodeString.left
        .map(ex => Err(s"Failed to decode string ContentType: $contentType, charset: $chs, err: ${ex.getMessage}"))
    )
  }
}