diff --git a/modules/core/src/main/scala/sangria/execution/FutureResolver.scala b/modules/core/src/main/scala/sangria/execution/FutureResolver.scala index d1640459..9e49a619 100644 --- a/modules/core/src/main/scala/sangria/execution/FutureResolver.scala +++ b/modules/core/src/main/scala/sangria/execution/FutureResolver.scala @@ -1405,7 +1405,11 @@ private[execution] class FutureResolver[Ctx]( if (isUndefinedValue(value)) None else { - val coerced = scalar.coerceOutput(value, marshaller.capabilities) + val corcedInput = scalar + .coerceUserInput(value) + // Do we need a specific exepction here? + .fold(e => throw new ValidationError(Vector(e), exceptionHandler), identity) + val coerced = scalar.coerceOutput(corcedInput, marshaller.capabilities) if (isUndefinedValue(coerced)) { None diff --git a/modules/core/src/main/scala/sangria/schema/ResolverBasedAstSchemaBuilder.scala b/modules/core/src/main/scala/sangria/schema/ResolverBasedAstSchemaBuilder.scala index d738f362..fb3fdeeb 100644 --- a/modules/core/src/main/scala/sangria/schema/ResolverBasedAstSchemaBuilder.scala +++ b/modules/core/src/main/scala/sangria/schema/ResolverBasedAstSchemaBuilder.scala @@ -587,7 +587,7 @@ object ResolverBasedAstSchemaBuilder { case v: String => safe(v.toDouble, "Float", value) case _ => invalidType("Float", value) } - case _ => coerced + case _ => t.coerceUserInput(coerced).fold(e => invalidType(t.name, value), identity) } } diff --git a/modules/core/src/test/scala/sangria/marshalling/IonSupportSpec.scala b/modules/core/src/test/scala/sangria/marshalling/IonSupportSpec.scala index ee0154fc..3b3df168 100644 --- a/modules/core/src/test/scala/sangria/marshalling/IonSupportSpec.scala +++ b/modules/core/src/test/scala/sangria/marshalling/IonSupportSpec.scala @@ -40,6 +40,7 @@ class IonSupportSpec extends AnyWordSpec with Matchers with FutureResultSupport else dateFormat.format(d), coerceUserInput = { case s: String => parseDate(s) + case d: Date => Right(d) case _ => Left(DateCoercionViolation) }, coerceInput = { @@ -51,13 +52,20 @@ class IonSupportSpec extends AnyWordSpec with Matchers with FutureResultSupport val BlobType = ScalarType[Array[Byte]]( "Blob", coerceOutput = (d, _) => d, - coerceUserInput = _ => Left(BinaryCoercionViolation), - coerceInput = _ => Left(BinaryCoercionViolation)) + coerceUserInput = { + case bs: Array[Byte] => Right(bs) + case _ => Left(BinaryCoercionViolation) + }, + coerceInput = _ => Left(BinaryCoercionViolation) + ) val ClobType = ScalarType[Array[Byte]]( "Clob", coerceOutput = (d, _) => d, - coerceUserInput = _ => Left(BinaryCoercionViolation), + coerceUserInput = { + case bs: Array[Byte] => Right(bs) + case _ => Left(BinaryCoercionViolation) + }, coerceInput = _ => Left(BinaryCoercionViolation), scalarInfo = Set(IonClobScalar) ) diff --git a/modules/core/src/test/scala/sangria/schema/CustomScalarSpec.scala b/modules/core/src/test/scala/sangria/schema/CustomScalarSpec.scala index 6ba2c9a5..1ba8e6ff 100644 --- a/modules/core/src/test/scala/sangria/schema/CustomScalarSpec.scala +++ b/modules/core/src/test/scala/sangria/schema/CustomScalarSpec.scala @@ -30,6 +30,7 @@ class CustomScalarSpec extends AnyWordSpec with Matchers { coerceOutput = (d, _) => dateFormat.format(d), coerceUserInput = { case s: String => parseDate(s) + case d: Date => Right(d) case _ => Left(DateCoercionViolation) }, coerceInput = { diff --git a/modules/core/src/test/scala/sangria/schema/ResolverBasedAstSchemaBuilderSpec.scala b/modules/core/src/test/scala/sangria/schema/ResolverBasedAstSchemaBuilderSpec.scala index cbf6e785..55127386 100644 --- a/modules/core/src/test/scala/sangria/schema/ResolverBasedAstSchemaBuilderSpec.scala +++ b/modules/core/src/test/scala/sangria/schema/ResolverBasedAstSchemaBuilderSpec.scala @@ -34,6 +34,7 @@ class ResolverBasedAstSchemaBuilderSpec extends AnyWordSpec with Matchers with F "UUID", coerceOutput = (v, _) => v.toString, coerceUserInput = { + case uuid: UUID => Right(uuid) case s: String => parseUuid(s) case _ => Left(UUIDViolation) },