Я хочу декодировать необязательный параметр запроса в моем коде Scala. Я использую http4s. Параметр имеет форму ?part=35/43
. Конечная цель — сохранить эту дробь как Type Part = (Int, Int)
, чтобы мы могли иметь (35, 43)
в качестве кортежа для дальнейшего использования в коде. Я создал такой объект, как: https://http4s.org/v0.18/dsl/#Optional-query-parameters
object OptionalPartitionQueryParamMatcher
extends OptionalValidatingQueryParamDecoderMatcher[Part]("part")
Теперь OptionalValidatingQueryParamDecoderMatcher
нужен неявный QueryParamDecoder[Part]
в области видимости.
Для этого я создал неявный val, который должен проверить, действительно ли у нас есть допустимая дробь, то есть оба символа должны быть цифрой (а не a/1
или b/c
и т. д.), а дробь должна быть меньше 1 (1/2
, 5/8
и т. д.):
implicit val ev: QueryParamDecoder[Part] =
new QueryParamDecoder[Part] {
def decode(
partition: QueryParameterValue
): ValidatedNel[ParseFailure, Part] = {
val partAndPartitions = partition.value.split("/")
Validated
.catchOnly[NumberFormatException] {
val part = partAndPartitions(0).toInt
val partitions = partAndPartitions(1).toInt
if (
partAndPartitions.length != 2 || part > partitions || part <= 0 || partitions <= 0
) {
throw new IllegalArgumentException
}
(part, partitions)
}
.leftMap(e => ParseFailure("Invalid query parameter part", e.getMessage))
.toValidatedNel
}
}
Проблема с приведенным выше кодом заключается в том, что он ловит только NumberFormatException
(это тоже, когда он не может преобразовать строку в Int, используя .toInt
), но что, если я введу что-то вроде ?part=/1
, он должен поймать ArrayIndexOutOfBoundsException
, потому что я запрашиваю первые два значения в массиве или, скажем, IllegalArgumentException
, когда дробь вообще недействительна. Как я могу добиться этого, поймав все за один проход? Спасибо!