@@ -154,18 +154,60 @@ def generateBySpec(
154154 case Dialect .Scala3 => s " package $resourcesPkg" ,
155155 " " ,
156156 config.httpSource match {
157- case HttpSource .Sttp4 => " import sttp.model.*\n import sttp.client4.*"
157+ case HttpSource .Sttp4 =>
158+ " import sttp.model.*\n import sttp.client4.*, sttp.client4.ResponseException.{DeserializationException, UnexpectedStatusCode}"
158159 case HttpSource .Sttp3 => " import sttp.model.*\n import sttp.client3.*"
159160 },
161+ config.jsonCodec match {
162+ case JsonCodec .ZioJson => " import zio.json.*"
163+ case JsonCodec .Jsoniter => " import com.github.plokhotnyuk.jsoniter_scala.core.*"
164+ },
160165 config.dialect match
161166 case Dialect .Scala3 => " " ,
162167 s " val resourceRequest: ${
163168 if config.httpSource == HttpSource .Sttp3 then " RequestT[Empty, Either[String, String], Any]"
164169 else " PartialRequest[Either[String, String]]"
165170 } = basicRequest.headers(Header.contentType(MediaType.ApplicationJson)) " ,
171+ " " ,
166172 s " export ${config.outPkg}.QueryParameters " ,
167- config.dialect match
168- case Dialect .Scala3 => " "
173+ " " ,
174+ (config.httpSource, config.jsonCodec) match
175+ case (HttpSource .Sttp4 , JsonCodec .Jsoniter ) =>
176+ """ |def asJson[T : JsonValueCodec]: ResponseAs[Either[ResponseException[String], T]] =
177+ | asByteArrayAlways.mapWithMetadata((bytes, metadata) =>
178+ | if metadata.isSuccess then
179+ | try {
180+ | Right(readFromArray[T](bytes))
181+ | } catch {
182+ | case e: Exception =>
183+ | Left(DeserializationException(String(bytes, java.nio.charset.StandardCharsets.UTF_8), e, metadata))
184+ | }
185+ | else Left(UnexpectedStatusCode(String(bytes, java.nio.charset.StandardCharsets.UTF_8), metadata))
186+ | )""" .stripMargin
187+ case (HttpSource .Sttp3 , JsonCodec .Jsoniter ) =>
188+ """ |def asJson[T : JsonValueCodec]: ResponseAs[Either[ResponseException[String, Exception], T], Any] =
189+ | asByteArrayAlways.mapWithMetadata((bytes, metadata) =>
190+ | if metadata.isSuccess then
191+ | try {
192+ | Right(readFromArray[T](bytes))
193+ | } catch {
194+ | case e: Exception =>
195+ | Left(DeserializationException(String(bytes, java.nio.charset.StandardCharsets.UTF_8), e))
196+ | }
197+ | else Left(HttpError(String(bytes, java.nio.charset.StandardCharsets.UTF_8), metadata.code))
198+ | )""" .stripMargin
199+ case (HttpSource .Sttp4 , JsonCodec .ZioJson ) =>
200+ """ |def asJson[T : JsonDecoder]: ResponseAs[Either[ResponseException[String], T]] =
201+ | asStringAlways.mapWithMetadata((body, metadata) =>
202+ | if metadata.isSuccess then body.fromJson[T].left.map(e => DeserializationException(body, Exception(e), metadata))
203+ | else Left(UnexpectedStatusCode(body, metadata))
204+ | )""" .stripMargin
205+ case (HttpSource .Sttp3 , JsonCodec .ZioJson ) =>
206+ """ |def asJson[T : JsonDecoder]: ResponseAs[Either[ResponseException[String, Exception], T], Any] =
207+ | asStringAlways.mapWithMetadata((body, metadata) =>
208+ | if metadata.isSuccess then body.fromJson[T].left.map(e => DeserializationException(body, Exception(e)))
209+ | else Left(HttpError(body, metadata.code))
210+ | )""" .stripMargin
169211 ).mkString(" \n " )
170212 )
171213 List (path.toFile())
@@ -254,20 +296,17 @@ def resourceCode(
254296 hasProps : SchemaPath => Boolean ,
255297 commonQueryParams : Map [String , Parameter ]
256298) =
299+ val sttpClientPkg = httpSource match
300+ case HttpSource .Sttp4 => " sttp.client4"
301+ case HttpSource .Sttp3 => " sttp.client3"
302+
257303 List (
258304 s " package $pkg" ,
259305 " " ,
260306 s " import $schemasPkg.* " ,
261307 s " import $resourcesPkg.* " ,
262308 " " ,
263- httpSource match {
264- case HttpSource .Sttp4 => " import sttp.model.Uri, sttp.model.Uri.PathSegment, sttp.client4.*"
265- case HttpSource .Sttp3 => " import sttp.model.Uri, sttp.model.Uri.PathSegment, sttp.client3.*"
266- },
267- jsonCodec match {
268- case JsonCodec .ZioJson => " import zio.json.*"
269- case JsonCodec .Jsoniter => " import com.github.plokhotnyuk.jsoniter_scala.core.*"
270- },
309+ s " import sttp.model.Uri, sttp.model.Uri.PathSegment, $sttpClientPkg.* " ,
271310 " " ,
272311 s " object ${resourceName} { " +
273312 resource.methods
@@ -351,35 +390,18 @@ def resourceCode(
351390
352391 def responseType (t : String ) =
353392 httpSource match
354- case HttpSource .Sttp4 => s " Request[Either[String, $t]] "
393+ case HttpSource .Sttp4 =>
394+ s " Request[Either[ ${if t == " String" then " String" else " ResponseException[String]" }, $t]] "
355395 case HttpSource .Sttp3 =>
356- s " RequestT[Identity, Either[String, $t], Any] "
396+ s " RequestT[Identity, Either[ ${ if t == " String" then " String " else " ResponseException[String, Exception] " } , $t], Any] "
357397
358398 val (resType, mapResponse) = v.response match
359399 case Some (r) if r.schemaPath.forall(hasProps) =>
360400 val bodyType = r.scalaType(arrType)
361401
362402 (
363403 responseType(bodyType),
364- jsonCodec match
365- case JsonCodec .ZioJson =>
366- s """ |.response(
367- | asStringAlways.mapWithMetadata((body, metadata) =>
368- | if (metadata.isSuccess) then body.fromJson[ $bodyType] else Left(body)
369- | )
370- |) """ .stripMargin
371- case JsonCodec .Jsoniter =>
372- s """ |.response(
373- | asByteArrayAlways.mapWithMetadata((bytes, metadata) =>
374- | if (metadata.isSuccess) {
375- | try {
376- | Right(readFromArray[ $bodyType](bytes))
377- | } catch {
378- | case e: Throwable => Left(e.getMessage())
379- | }
380- | } else Left(String(bytes, java.nio.charset.StandardCharsets.UTF_8))
381- | )
382- |) """ .stripMargin
404+ s " .response(asJson[ $bodyType]) "
383405 )
384406 case _ => (responseType(" String" ), " " )
385407
0 commit comments