Skip to content

Commit

Permalink
Added getAs for QueryParams - errors enhancement (#2510)
Browse files Browse the repository at this point in the history
* Added getAs for QueryParams - errors enhancement

* Added getAs for QueryParams - amendments
  • Loading branch information
BanyMaciej authored Nov 8, 2023
1 parent 40c2961 commit 735d9b7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 22 deletions.
23 changes: 10 additions & 13 deletions zio-http/src/main/scala/zio/http/QueryParams.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package zio.http

import java.nio.charset.Charset

import zio.{Chunk, IO, ZIO}
import zio.{Chunk, IO, NonEmptyChunk, ZIO}

import zio.http.codec.TextCodec
import zio.http.internal.QueryParamEncoding
Expand Down Expand Up @@ -91,17 +91,14 @@ final case class QueryParams(map: Map[String, Chunk[String]]) {
/**
* Retrieves all typed query parameter values having the specified name.
*/
def getAllAs[A](key: String)(implicit codec: TextCodec[A]): Either[QueryParamsError, Chunk[A]] =
map.get(key) match {
case Some(params) =>
params
.map(param => codec.decode(param).toRight(QueryParamsError.Malformed(key, param, codec)))
.partitionMap(identity) match {
case (errors, _) if errors.nonEmpty => Left(QueryParamsError.MultiMalformed(errors))
case (_, typedParams) => Right(typedParams)
}
case None => Left(QueryParamsError.Missing(key))
}
def getAllAs[A](key: String)(implicit codec: TextCodec[A]): Either[QueryParamsError, Chunk[A]] = for {
params <- map.get(key).toRight(QueryParamsError.Missing(key))
(failed, typed) = params.partitionMap(p => codec.decode(p).toRight(p))
result <- NonEmptyChunk
.fromChunk(failed)
.map(fails => QueryParamsError.Malformed(key, codec, fails))
.toLeft(typed)
} yield result

/**
* Retrieves all typed query parameter values having the specified name as
Expand All @@ -120,7 +117,7 @@ final case class QueryParams(map: Map[String, Chunk[String]]) {
*/
def getAs[A](key: String)(implicit codec: TextCodec[A]): Either[QueryParamsError, A] = for {
param <- get(key).toRight(QueryParamsError.Missing(key))
typedParam <- codec.decode(param).toRight(QueryParamsError.Malformed(key, param, codec))
typedParam <- codec.decode(param).toRight(QueryParamsError.Malformed(key, codec, NonEmptyChunk(param)))
} yield typedParam

/**
Expand Down
16 changes: 7 additions & 9 deletions zio-http/src/main/scala/zio/http/QueryParamsError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import java.nio.charset.Charset

import scala.util.control.NoStackTrace

import zio.Chunk
import zio.{Chunk, NonEmptyChunk}

import zio.http.codec.TextCodec
import zio.http.internal.QueryParamEncoding
Expand All @@ -30,15 +30,13 @@ sealed trait QueryParamsError extends Exception with NoStackTrace {
def message: String
}
object QueryParamsError {
final case class Missing(queryParamName: String) extends QueryParamsError {
def message = s"Missing query parameter with name $queryParamName"
final case class Missing(name: String) extends QueryParamsError {
def message = s"Missing query parameter with name $name"
}

final case class Malformed(name: String, value: String, codec: TextCodec[_]) extends QueryParamsError {
def message = s"Unable to decode query parameter with name $name and value $value using $codec"
}

final case class MultiMalformed(chunk: Chunk[Malformed]) extends QueryParamsError {
def message: String = chunk.map(_.getMessage()).mkString("; ")
final case class Malformed(name: String, codec: TextCodec[_], values: NonEmptyChunk[String])
extends QueryParamsError {
def message: String =
s"Unable to decode query parameter $name with values [ ${values.mkString(", ")} ] using ${codec.describe} codec"
}
}

0 comments on commit 735d9b7

Please sign in to comment.