From 7f68c32839e0950d2c1a5ab79f8f52d56e8631ff Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 01:26:21 +0530 Subject: [PATCH 01/11] fix:fmt --- .../scala/zio/http/ErrorResponseConfig.scala | 3 +- .../zio/http/codec/HttpContentCodec.scala | 55 +++++++++++++------ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala index 10237403a8..7f8e39f55c 100644 --- a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala +++ b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala @@ -22,6 +22,7 @@ final case class ErrorResponseConfig( withStackTrace: Boolean = false, maxStackTraceDepth: Int = 10, errorFormat: ErrorResponseConfig.ErrorFormat = ErrorResponseConfig.ErrorFormat.Html, + logCodecErrors: Boolean = false, ) object ErrorResponseConfig { @@ -34,7 +35,7 @@ object ErrorResponseConfig { val default: ErrorResponseConfig = ErrorResponseConfig() val debugConfig: ErrorResponseConfig = - ErrorResponseConfig(withErrorBody = true, withStackTrace = true, maxStackTraceDepth = 0) + ErrorResponseConfig(withErrorBody = true, withStackTrace = true, maxStackTraceDepth = 0, logCodecErrors = true) private[http] val configRef: FiberRef[ErrorResponseConfig] = FiberRef.unsafe.make(default)(Unsafe) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index 3f8a3f29a2..fe09bb3965 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -28,14 +28,21 @@ sealed trait HttpContentCodec[A] { self => HttpContentCodec.Choices(choices ++ that.choices) def decodeRequest(request: Request, config: CodecConfig): Task[A] = { - val contentType = mediaTypeFromContentTypeHeader(request) - lookup(contentType) match { - case Some((_, codec)) => - request.body.asChunk.flatMap { bytes => - ZIO.fromEither(codec.codec(config).decode(bytes)) - } - case None => - ZIO.fail(throw new IllegalArgumentException(s"No codec found for content type $contentType")) + ErrorResponseConfig.configRef.get.flatMap { config => + val contentType = mediaTypeFromContentTypeHeader(request) + lookup(contentType) match { + case Some((_, codec)) => + request.body.asChunk.flatMap { bytes => + ZIO + .fromEither(codec.codec(config).decode(bytes)) + .mapError(_ => CodecDecodeError(s"Failed to decode request body for media type: $contentType")) + .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) + } + case None => + ZIO + .fail(UnsupportedMediaTypeError(contentType)) + .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) + } } } @@ -43,14 +50,21 @@ sealed trait HttpContentCodec[A] { self => CodecConfig.codecRef.getWith(decodeRequest(request, _)) def decodeResponse(response: Response, config: CodecConfig): Task[A] = { - val contentType = mediaTypeFromContentTypeHeader(response) - lookup(contentType) match { - case Some((_, codec)) => - response.body.asChunk.flatMap { bytes => - ZIO.fromEither(codec.codec(config).decode(bytes)) - } - case None => - ZIO.fail(throw new IllegalArgumentException(s"No codec found for content type $contentType")) + ErrorResponseConfig.configRef.get.flatMap { config => + val contentType = mediaTypeFromContentTypeHeader(response) + lookup(contentType) match { + case Some((_, codec)) => + response.body.asChunk.flatMap { bytes => + ZIO + .fromEither(codec.codec(config).decode(bytes)) + .mapError(_ => CodecDecodeError(s"Failed to decode response body for media type: $contentType")) + .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) + } + case None => + ZIO + .fail(UnsupportedMediaTypeError(contentType)) + .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) + } } } @@ -180,6 +194,15 @@ sealed trait HttpContentCodec[A] { self => } +sealed trait CodecError extends Throwable +case class UnsupportedMediaTypeError(mediaType: MediaType) extends CodecError { + override def getMessage: String = s"Unsupported media type: $mediaType" +} + +case class CodecDecodeError(details: String) extends CodecError { + override def getMessage: String = s"Codec decode error: $details" +} + object HttpContentCodec { final case class Choices[A]( choices: ListMap[MediaType, BinaryCodecWithSchema[A]], From 5d436b82cedf857585c7d6b8ae6dd465236d5172 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 01:34:10 +0530 Subject: [PATCH 02/11] fix:fmt --- .../zio/http/codec/HttpContentCodec.scala | 68 +++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index fe09bb3965..1bfe385795 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -28,21 +28,27 @@ sealed trait HttpContentCodec[A] { self => HttpContentCodec.Choices(choices ++ that.choices) def decodeRequest(request: Request, config: CodecConfig): Task[A] = { - ErrorResponseConfig.configRef.get.flatMap { config => - val contentType = mediaTypeFromContentTypeHeader(request) - lookup(contentType) match { - case Some((_, codec)) => - request.body.asChunk.flatMap { bytes => - ZIO - .fromEither(codec.codec(config).decode(bytes)) - .mapError(_ => CodecDecodeError(s"Failed to decode request body for media type: $contentType")) - .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) - } - case None => + val contentType = mediaTypeFromContentTypeHeader(request) + lookup(contentType) match { + case Some((_, codec)) => + request.body.asChunk.flatMap { bytes => ZIO - .fail(UnsupportedMediaTypeError(contentType)) - .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) - } + .fromEither(codec.codec(config).decode(bytes)) + .mapError(_ => CodecDecodeError(s"Failed to decode request body for media type: $contentType")) + .tapError(error => + ErrorResponseConfig.configRef.get.flatMap { errConfig => + if (errConfig.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit + }, + ) + } + case None => + ZIO + .fail(UnsupportedMediaTypeError(contentType)) + .tapError(error => + ErrorResponseConfig.configRef.get.flatMap { errConfig => + if (errConfig.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit + }, + ) } } @@ -50,21 +56,27 @@ sealed trait HttpContentCodec[A] { self => CodecConfig.codecRef.getWith(decodeRequest(request, _)) def decodeResponse(response: Response, config: CodecConfig): Task[A] = { - ErrorResponseConfig.configRef.get.flatMap { config => - val contentType = mediaTypeFromContentTypeHeader(response) - lookup(contentType) match { - case Some((_, codec)) => - response.body.asChunk.flatMap { bytes => - ZIO - .fromEither(codec.codec(config).decode(bytes)) - .mapError(_ => CodecDecodeError(s"Failed to decode response body for media type: $contentType")) - .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) - } - case None => + val contentType = mediaTypeFromContentTypeHeader(response) + lookup(contentType) match { + case Some((_, codec)) => + response.body.asChunk.flatMap { bytes => ZIO - .fail(UnsupportedMediaTypeError(contentType)) - .tapError(error => if (config.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit) - } + .fromEither(codec.codec(config).decode(bytes)) + .mapError(_ => CodecDecodeError(s"Failed to decode response body for media type: $contentType")) + .tapError(error => + ErrorResponseConfig.configRef.get.flatMap { errConfig => + if (errConfig.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit + }, + ) + } + case None => + ZIO + .fail(UnsupportedMediaTypeError(contentType)) + .tapError(error => + ErrorResponseConfig.configRef.get.flatMap { errConfig => + if (errConfig.logCodecErrors) ZIO.logWarning(error.getMessage) else ZIO.unit + }, + ) } } From 1bc8bde39a61cab5852fd197c3078110467e0e8c Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:01:25 +0530 Subject: [PATCH 03/11] fix:fmt --- .../src/main/scala/zio/http/codec/HttpContentCodec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index 1bfe385795..7bcb1b67da 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -138,9 +138,9 @@ sealed trait HttpContentCodec[A] { self => private[http] def chooseFirstOrDefault( mediaTypes: Chunk[MediaTypeWithQFactor], - ): (MediaType, BinaryCodecWithSchema[A]) = + ): Either[UnsupportedMediaTypeError, (MediaType, BinaryCodecWithSchema[A])] = if (mediaTypes.isEmpty) { - (defaultMediaType, defaultBinaryCodecWithSchema) + Right((defaultMediaType, defaultBinaryCodecWithSchema)) } else { var i = 0 var result: (MediaType, BinaryCodecWithSchema[A]) = null @@ -150,8 +150,8 @@ sealed trait HttpContentCodec[A] { self => if (lookupResult.isDefined) result = lookupResult.get i += 1 } - if (result == null) (defaultMediaType, defaultBinaryCodecWithSchema) - else result + if (result == null) Left(UnsupportedMediaTypeError(mediaTypes.map(_.mediaType).mkString(", "))) + else Right(result) } def lookup(mediaType: MediaType): Option[(MediaType, BinaryCodecWithSchema[A])] From d8249a47ed842d82048431396a72e1097c9672e2 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:03:36 +0530 Subject: [PATCH 04/11] fix:fmt --- .../src/main/scala/zio/http/codec/HttpContentCodec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index 7bcb1b67da..1bfe385795 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -138,9 +138,9 @@ sealed trait HttpContentCodec[A] { self => private[http] def chooseFirstOrDefault( mediaTypes: Chunk[MediaTypeWithQFactor], - ): Either[UnsupportedMediaTypeError, (MediaType, BinaryCodecWithSchema[A])] = + ): (MediaType, BinaryCodecWithSchema[A]) = if (mediaTypes.isEmpty) { - Right((defaultMediaType, defaultBinaryCodecWithSchema)) + (defaultMediaType, defaultBinaryCodecWithSchema) } else { var i = 0 var result: (MediaType, BinaryCodecWithSchema[A]) = null @@ -150,8 +150,8 @@ sealed trait HttpContentCodec[A] { self => if (lookupResult.isDefined) result = lookupResult.get i += 1 } - if (result == null) Left(UnsupportedMediaTypeError(mediaTypes.map(_.mediaType).mkString(", "))) - else Right(result) + if (result == null) (defaultMediaType, defaultBinaryCodecWithSchema) + else result } def lookup(mediaType: MediaType): Option[(MediaType, BinaryCodecWithSchema[A])] From 1c834b866326b48d39424961918ca4102de48355 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:13:41 +0530 Subject: [PATCH 05/11] fix:fmt --- .../src/main/scala/zio/http/codec/HttpContentCodec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index 1bfe385795..73d5f919e8 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -138,9 +138,9 @@ sealed trait HttpContentCodec[A] { self => private[http] def chooseFirstOrDefault( mediaTypes: Chunk[MediaTypeWithQFactor], - ): (MediaType, BinaryCodecWithSchema[A]) = + ): Either[UnsupportedMediaTypeError, (MediaType, BinaryCodecWithSchema[A])] = if (mediaTypes.isEmpty) { - (defaultMediaType, defaultBinaryCodecWithSchema) + Right((defaultMediaType, defaultBinaryCodecWithSchema)) } else { var i = 0 var result: (MediaType, BinaryCodecWithSchema[A]) = null @@ -150,8 +150,8 @@ sealed trait HttpContentCodec[A] { self => if (lookupResult.isDefined) result = lookupResult.get i += 1 } - if (result == null) (defaultMediaType, defaultBinaryCodecWithSchema) - else result + if (result == null) Left(UnsupportedMediaTypeError(mediaTypes.head.mediaType)) + else Right(result) } def lookup(mediaType: MediaType): Option[(MediaType, BinaryCodecWithSchema[A])] From 4ee3e489ac9601234a42caa6285f42aa0be28a49 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:24:06 +0530 Subject: [PATCH 06/11] fix:fmt --- .../zio/http/codec/internal/BodyCodec.scala | 77 ++++++++++++------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/internal/BodyCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/internal/BodyCodec.scala index feb9f64ee1..fa77a098b5 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/internal/BodyCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/internal/BodyCodec.scala @@ -109,9 +109,11 @@ private[http] object BodyCodec { final case class Single[A](codec: HttpContentCodec[A], name: Option[String]) extends BodyCodec[A] { - def mediaType(accepted: Chunk[MediaTypeWithQFactor]): Option[MediaType] = - Some(codec.chooseFirstOrDefault(accepted)._1) - + def mediaType(accepted: Chunk[MediaTypeWithQFactor]): Option[MediaType] = + codec.chooseFirstOrDefault(accepted) match { + case Right((mediaType, _)) => Some(mediaType) + case Left(_) => None + } def decodeFromField(field: FormField, config: CodecConfig)(implicit trace: Trace): IO[Throwable, A] = { val codec0 = codec .lookup(field.contentType) @@ -139,27 +141,36 @@ private[http] object BodyCodec { def encodeToField(value: A, mediaTypes: Chunk[MediaTypeWithQFactor], name: String, config: CodecConfig)(implicit trace: Trace, ): FormField = { - val (mediaType, bc @ BinaryCodecWithSchema(_, _)) = codec.chooseFirstOrDefault(mediaTypes) - if (mediaType.binary) { - FormField.binaryField( - name, - bc.codec(config).encode(value), - mediaType, - ) - } else { - FormField.textField( - name, - bc.codec(config).encode(value).asString, - mediaType, - ) + codec.chooseFirstOrDefault(mediaTypes) match { + + case Right((mediaType, bc @ BinaryCodecWithSchema(_, _))) => + if (mediaType.binary) { + FormField.binaryField( + name, + bc.codec(config).encode(value), + mediaType, + ) + } else { + FormField.textField( + name, + bc.codec(config).encode(value).asString, + mediaType, + ) + } + case Left(error) => + throw new IllegalArgumentException(s"Unsupported media type: ${error.mediaType}") } } def encodeToBody(value: A, mediaTypes: Chunk[MediaTypeWithQFactor], config: CodecConfig)(implicit trace: Trace, ): Body = { - val (mediaType, bc @ BinaryCodecWithSchema(_, _)) = codec.chooseFirstOrDefault(mediaTypes) - Body.fromChunk(bc.codec(config).encode(value), mediaType) + codec.chooseFirstOrDefault(mediaTypes) match { + case Right((mediaType, bc @ BinaryCodecWithSchema(_, _))) => + Body.fromChunk(bc.codec(config).encode(value), mediaType) + case Left(error) => + throw new IllegalArgumentException(s"Unsupported media type: ${error.mediaType}") + } } type Element = A @@ -169,8 +180,10 @@ private[http] object BodyCodec { extends BodyCodec[ZStream[Any, Nothing, E]] { def mediaType(accepted: Chunk[MediaTypeWithQFactor]): Option[MediaType] = - Some(codec.chooseFirstOrDefault(accepted)._1) - + codec.chooseFirstOrDefault(accepted) match { + case Right((mediaType, _)) => Some(mediaType) + case Left(_) => None + } override def decodeFromField(field: FormField, config: CodecConfig)(implicit trace: Trace, ): IO[Throwable, ZStream[Any, Nothing, E]] = @@ -200,12 +213,16 @@ private[http] object BodyCodec { )(implicit trace: Trace, ): FormField = { - val (mediaType, bc) = codec.chooseFirstOrDefault(mediaTypes) - FormField.streamingBinaryField( - name, - value >>> bc.codec(config).streamEncoder, - mediaType, - ) + codec.chooseFirstOrDefault(mediaTypes) match { + case Right((mediaType, bc)) => + FormField.streamingBinaryField( + name, + value >>> bc.codec(config).streamEncoder, + mediaType, + ) + case Left(error) => + throw new IllegalArgumentException(s"Unsupported media type: ${error.mediaType}") + } } override def encodeToBody( @@ -215,8 +232,12 @@ private[http] object BodyCodec { )(implicit trace: Trace, ): Body = { - val (mediaType, bc @ BinaryCodecWithSchema(_, _)) = codec.chooseFirstOrDefault(mediaTypes) - Body.fromStreamChunked(value >>> bc.codec(config).streamEncoder).contentType(mediaType) + codec.chooseFirstOrDefault(mediaTypes) match { + case Right((mediaType, bc @ BinaryCodecWithSchema(_, _))) => + Body.fromStreamChunked(value >>> bc.codec(config).streamEncoder).contentType(mediaType) + case Left(error) => + throw new IllegalArgumentException(s"Unsupported media type: ${error.mediaType}") + } } type Element = E From 37befc41d91815c6ebd848a80c128b6e2a57ea31 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:41:50 +0530 Subject: [PATCH 07/11] Implement codec error handling and text/plain support with detailed logging --- .../shared/src/main/scala/zio/http/codec/HttpContentCodec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index 73d5f919e8..bc435aa008 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -150,7 +150,7 @@ sealed trait HttpContentCodec[A] { self => if (lookupResult.isDefined) result = lookupResult.get i += 1 } - if (result == null) Left(UnsupportedMediaTypeError(mediaTypes.head.mediaType)) + if (result == null) Right((defaultMediaType, defaultBinaryCodecWithSchema)) else Right(result) } From 27113683c320012d58b7f33a88a99e9bf4b631ed Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Sun, 10 Nov 2024 02:52:35 +0530 Subject: [PATCH 08/11] Implement codec error handling and text/plain support with detailed logging --- .../src/main/scala/zio/http/codec/HttpContentCodec.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala index bc435aa008..30ca37c7ba 100644 --- a/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala +++ b/zio-http/shared/src/main/scala/zio/http/codec/HttpContentCodec.scala @@ -150,8 +150,10 @@ sealed trait HttpContentCodec[A] { self => if (lookupResult.isDefined) result = lookupResult.get i += 1 } - if (result == null) Right((defaultMediaType, defaultBinaryCodecWithSchema)) - else Right(result) + if (result == null) { + ZIO.logWarning(s"Unsupported media type: ${mediaTypes.head.mediaType}") + Right((defaultMediaType, defaultBinaryCodecWithSchema)) + } else Right(result) } def lookup(mediaType: MediaType): Option[(MediaType, BinaryCodecWithSchema[A])] From a8d9b5fbcc981c595df145e75285be9075654349 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:43:31 +0530 Subject: [PATCH 09/11] add review comments --- .../scala/zio/http/ErrorResponseConfig.scala | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala index 7f8e39f55c..4874660111 100644 --- a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala +++ b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala @@ -23,7 +23,34 @@ final case class ErrorResponseConfig( maxStackTraceDepth: Int = 10, errorFormat: ErrorResponseConfig.ErrorFormat = ErrorResponseConfig.ErrorFormat.Html, logCodecErrors: Boolean = false, -) +) { + + /** + * Backward-compatible copy method for compatibility with older code. + * + * Omits the new `logCodecErrors` parameter, which defaults to `false` in + * older usage scenarios. + */ + def copy( + withErrorBody: Boolean = this.withErrorBody, + withStackTrace: Boolean = this.withStackTrace, + maxStackTraceDepth: Int = this.maxStackTraceDepth, + errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, + ): ErrorResponseConfig = + new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) + + /** + * Full copy method including all parameters. + */ + def copy( + withErrorBody: Boolean = this.withErrorBody, + withStackTrace: Boolean = this.withStackTrace, + maxStackTraceDepth: Int = this.maxStackTraceDepth, + errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, + logCodecErrors: Boolean = this.logCodecErrors, + ): ErrorResponseConfig = + new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) +} object ErrorResponseConfig { sealed trait ErrorFormat { val mediaType: MediaType } @@ -40,6 +67,14 @@ object ErrorResponseConfig { private[http] val configRef: FiberRef[ErrorResponseConfig] = FiberRef.unsafe.make(default)(Unsafe) + def apply( + withErrorBody: Boolean, + withStackTrace: Boolean, + maxStackTraceDepth: Int, + errorFormat: ErrorFormat, + ): ErrorResponseConfig = + new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors = false) + val debug: HandlerAspect[Any, Unit] = Middleware.runBefore(setConfig(debugConfig)) From 84d42b06663fdba788075e8ccd63020d614f1a38 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:55:46 +0530 Subject: [PATCH 10/11] add review comments --- .../scala/zio/http/ErrorResponseConfig.scala | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala index 4874660111..6fc75779e4 100644 --- a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala +++ b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala @@ -23,34 +23,7 @@ final case class ErrorResponseConfig( maxStackTraceDepth: Int = 10, errorFormat: ErrorResponseConfig.ErrorFormat = ErrorResponseConfig.ErrorFormat.Html, logCodecErrors: Boolean = false, -) { - - /** - * Backward-compatible copy method for compatibility with older code. - * - * Omits the new `logCodecErrors` parameter, which defaults to `false` in - * older usage scenarios. - */ - def copy( - withErrorBody: Boolean = this.withErrorBody, - withStackTrace: Boolean = this.withStackTrace, - maxStackTraceDepth: Int = this.maxStackTraceDepth, - errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, - ): ErrorResponseConfig = - new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) - - /** - * Full copy method including all parameters. - */ - def copy( - withErrorBody: Boolean = this.withErrorBody, - withStackTrace: Boolean = this.withStackTrace, - maxStackTraceDepth: Int = this.maxStackTraceDepth, - errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, - logCodecErrors: Boolean = this.logCodecErrors, - ): ErrorResponseConfig = - new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) -} +) object ErrorResponseConfig { sealed trait ErrorFormat { val mediaType: MediaType } @@ -60,13 +33,7 @@ object ErrorResponseConfig { case object Json extends ErrorFormat { val mediaType: MediaType = MediaType.application.json } } - val default: ErrorResponseConfig = ErrorResponseConfig() - val debugConfig: ErrorResponseConfig = - ErrorResponseConfig(withErrorBody = true, withStackTrace = true, maxStackTraceDepth = 0, logCodecErrors = true) - - private[http] val configRef: FiberRef[ErrorResponseConfig] = - FiberRef.unsafe.make(default)(Unsafe) - + // Backward-compatible apply method for older usage, without logCodecErrors def apply( withErrorBody: Boolean, withStackTrace: Boolean, @@ -75,6 +42,14 @@ object ErrorResponseConfig { ): ErrorResponseConfig = new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors = false) + val default: ErrorResponseConfig = ErrorResponseConfig() + + val debugConfig: ErrorResponseConfig = + ErrorResponseConfig(withErrorBody = true, withStackTrace = true, maxStackTraceDepth = 0, logCodecErrors = true) + + private[http] val configRef: FiberRef[ErrorResponseConfig] = + FiberRef.unsafe.make(default)(Unsafe) + val debug: HandlerAspect[Any, Unit] = Middleware.runBefore(setConfig(debugConfig)) From 9aca95d38d3b7fa9109fef52fb8cbed84b5442f1 Mon Sep 17 00:00:00 2001 From: Vamshi Maskuri <117595548+varshith257@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:35:07 +0530 Subject: [PATCH 11/11] Update ErrorResponseConfig.scala --- .../scala/zio/http/ErrorResponseConfig.scala | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala index 6fc75779e4..3814811f30 100644 --- a/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala +++ b/zio-http/shared/src/main/scala/zio/http/ErrorResponseConfig.scala @@ -23,7 +23,34 @@ final case class ErrorResponseConfig( maxStackTraceDepth: Int = 10, errorFormat: ErrorResponseConfig.ErrorFormat = ErrorResponseConfig.ErrorFormat.Html, logCodecErrors: Boolean = false, -) +){ + + /** + * Backward-compatible copy method for compatibility with older code. + * + * Omits the new `logCodecErrors` parameter, which defaults to `false` in + * older usage scenarios. + */ + def copy( + withErrorBody: Boolean = this.withErrorBody, + withStackTrace: Boolean = this.withStackTrace, + maxStackTraceDepth: Int = this.maxStackTraceDepth, + errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, + ): ErrorResponseConfig = + new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) + + /** + * Full copy method including all parameters. + */ + def copyWithLog( + withErrorBody: Boolean = this.withErrorBody, + withStackTrace: Boolean = this.withStackTrace, + maxStackTraceDepth: Int = this.maxStackTraceDepth, + errorFormat: ErrorResponseConfig.ErrorFormat = this.errorFormat, + logCodecErrors: Boolean = this.logCodecErrors, + ): ErrorResponseConfig = + new ErrorResponseConfig(withErrorBody, withStackTrace, maxStackTraceDepth, errorFormat, logCodecErrors) +} object ErrorResponseConfig { sealed trait ErrorFormat { val mediaType: MediaType }