From fbcd20814ad9314a02190b461ac0ee52dd7bba80 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Tue, 18 Jul 2017 20:52:39 +0700 Subject: [PATCH] Scalar type `serialize` method now throws `InvariantViolation` and `parseValue` throws `UserError` --- src/Type/Definition/FloatType.php | 26 +++++++++++++++---------- src/Type/Definition/IDType.php | 19 +++++++++++++++--- src/Type/Definition/IntType.php | 31 +++++++++++++++--------------- src/Type/Definition/StringType.php | 17 ++++++++++++++-- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/src/Type/Definition/FloatType.php b/src/Type/Definition/FloatType.php index 17e5b53..d5de717 100644 --- a/src/Type/Definition/FloatType.php +++ b/src/Type/Definition/FloatType.php @@ -1,6 +1,7 @@ coerceFloat($value); + return $this->coerceFloat($value, false); } /** @@ -40,24 +41,29 @@ values as specified by */ public function parseValue($value) { - return $this->coerceFloat($value); + return $this->coerceFloat($value, true); } /** - * @param $value + * @param mixed $value + * @param bool $isInput * @return float|null */ - private function coerceFloat($value) + private function coerceFloat($value, $isInput) { + if (is_numeric($value) || $value === true || $value === false) { + return (float) $value; + } + if ($value === '') { - throw new UserError( - 'Float cannot represent non numeric value: (empty string)' + $err = 'Float cannot represent non numeric value: (empty string)'; + } else { + $err = sprintf( + 'Float cannot represent non numeric value: %s', + $isInput ? Utils::printSafeJson($value) : Utils::printSafe($value) ); } - if (is_numeric($value) || $value === true || $value === false) { - return (float)$value; - } - throw new UserError(sprintf('Float cannot represent non numeric value: %s', Utils::printSafe($value))); + throw ($isInput ? new UserError($err) : new InvariantViolation($err)); } /** diff --git a/src/Type/Definition/IDType.php b/src/Type/Definition/IDType.php index 89f4ff2..a41eb22 100644 --- a/src/Type/Definition/IDType.php +++ b/src/Type/Definition/IDType.php @@ -1,10 +1,11 @@ parseValue($value); + if ($value === true) { + return 'true'; + } + if ($value === false) { + return 'false'; + } + if ($value === null) { + return 'null'; + } + if (!is_scalar($value)) { + throw new InvariantViolation("ID type cannot represent non scalar value: " . Utils::printSafe($value)); + } + return (string) $value; } /** @@ -52,7 +65,7 @@ When expected as an input type, any string (such as `"4"`) or integer return 'null'; } if (!is_scalar($value)) { - throw new UserError("String cannot represent non scalar value: " . Utils::printSafe($value)); + throw new UserError("ID type cannot represent non scalar value: " . Utils::printSafeJson($value)); } return (string) $value; } diff --git a/src/Type/Definition/IntType.php b/src/Type/Definition/IntType.php index 73d008c..35e66e4 100644 --- a/src/Type/Definition/IntType.php +++ b/src/Type/Definition/IntType.php @@ -38,7 +38,7 @@ values. Int can represent values between -(2^31) and 2^31 - 1. '; */ public function serialize($value) { - return $this->coerceInt($value); + return $this->coerceInt($value, false); } /** @@ -47,21 +47,20 @@ values. Int can represent values between -(2^31) and 2^31 - 1. '; */ public function parseValue($value) { - try { - return $this->coerceInt($value); - } catch (InvariantViolation $e) { - throw new UserError($e->getMessage(), $e->getCode(), $e); - } + return $this->coerceInt($value, true); } /** * @param $value + * @param bool $isInput * @return int|null */ - private function coerceInt($value) + private function coerceInt($value, $isInput) { + $errClass = $isInput ? UserError::class : InvariantViolation::class; + if ($value === '') { - throw new InvariantViolation( + throw new $errClass( 'Int cannot represent non 32-bit signed integer value: (empty string)' ); } @@ -69,22 +68,24 @@ values. Int can represent values between -(2^31) and 2^31 - 1. '; return (int) $value; } if (!is_numeric($value) || $value > self::MAX_INT || $value < self::MIN_INT) { - throw new InvariantViolation( - sprintf('Int cannot represent non 32-bit signed integer value: %s', Utils::printSafe($value)) - ); + throw new $errClass(sprintf( + 'Int cannot represent non 32-bit signed integer value: %s', + $isInput ? Utils::printSafeJson($value) : Utils::printSafe($value) + )); } $num = (float) $value; // The GraphQL specification does not allow serializing non-integer values // as Int to avoid accidental data loss. // Examples: 1.0 == 1; 1.1 != 1, etc - if ($num != (int)$value) { + if ($num != (int) $value) { // Additionally account for scientific notation (i.e. 1e3), because (float)'1e3' is 1000, but (int)'1e3' is 1 $trimmed = floor($num); if ($trimmed !== $num) { - throw new InvariantViolation( - 'Int cannot represent non-integer value: ' . Utils::printSafe($value) - ); + throw new $errClass(sprintf( + 'Int cannot represent non-integer value: %s', + $isInput ? Utils::printSafeJson($value) : Utils::printSafe($value) + )); } } return (int) $value; diff --git a/src/Type/Definition/StringType.php b/src/Type/Definition/StringType.php index 182643e..7b82481 100644 --- a/src/Type/Definition/StringType.php +++ b/src/Type/Definition/StringType.php @@ -1,9 +1,10 @@ parseValue($value); + if ($value === true) { + return 'true'; + } + if ($value === false) { + return 'false'; + } + if ($value === null) { + return 'null'; + } + if (!is_scalar($value)) { + throw new InvariantViolation("String cannot represent non scalar value: " . Utils::printSafe($value)); + } + return (string) $value; } /**