feature #21239 [Serializer] throw more specific exceptions (xabbuh)

This PR was merged into the 3.4 branch.

Discussion
----------

[Serializer] throw more specific exceptions

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #20534
| License       | MIT
| Doc PR        |

Commits
-------

aa30d04243 [Serializer] throw more specific exceptions
This commit is contained in:
Fabien Potencier 2017-09-27 07:28:41 -07:00
commit 9f56a9efa7
10 changed files with 77 additions and 31 deletions

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
/**
* Decodes JSON data.
@ -73,7 +73,7 @@ class JsonDecode implements DecoderInterface
*
* @return mixed
*
* @throws UnexpectedValueException
* @throws NotEncodableValueException
*
* @see http://php.net/json_decode json_decode
*/
@ -88,7 +88,7 @@ class JsonDecode implements DecoderInterface
$decodedData = json_decode($data, $associative, $recursionDepth, $options);
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(json_last_error_msg());
throw new NotEncodableValueException(json_last_error_msg());
}
return $decodedData;

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
/**
* Encodes JSON data.
@ -40,7 +40,7 @@ class JsonEncode implements EncoderInterface
$encodedJson = json_encode($data, $context['json_encode_options']);
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(json_last_error_msg());
throw new NotEncodableValueException(json_last_error_msg());
}
return $encodedJson;

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
/**
* Encodes XML data.
@ -78,7 +78,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
public function decode($data, $format, array $context = array())
{
if ('' === trim($data)) {
throw new UnexpectedValueException('Invalid XML data, it can not be empty.');
throw new NotEncodableValueException('Invalid XML data, it can not be empty.');
}
$internalErrors = libxml_use_internal_errors(true);
@ -94,13 +94,13 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
if ($error = libxml_get_last_error()) {
libxml_clear_errors();
throw new UnexpectedValueException($error->message);
throw new NotEncodableValueException($error->message);
}
$rootNode = null;
foreach ($dom->childNodes as $child) {
if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
throw new UnexpectedValueException('Document types are not allowed.');
throw new NotEncodableValueException('Document types are not allowed.');
}
if (!$rootNode && XML_PI_NODE !== $child->nodeType) {
$rootNode = $child;
@ -380,7 +380,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
*
* @return bool
*
* @throws UnexpectedValueException
* @throws NotEncodableValueException
*/
private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null)
{
@ -437,7 +437,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
return $this->appendNode($parentNode, $data, 'data');
}
throw new UnexpectedValueException(sprintf('An unexpected value could not be serialized: %s', var_export($data, true)));
throw new NotEncodableValueException(sprintf('An unexpected value could not be serialized: %s', var_export($data, true)));
}
/**
@ -485,7 +485,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
*
* @return bool
*
* @throws UnexpectedValueException
* @throws NotEncodableValueException
*/
private function selectNodeType(\DOMNode $node, $val)
{

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Exception;
/**
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
*/
class NotEncodableValueException extends UnexpectedValueException
{
}

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Exception;
/**
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
*/
class NotNormalizableValueException extends UnexpectedValueException
{
}

View File

@ -15,7 +15,7 @@ use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\PropertyInfo\Type;
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
@ -200,7 +200,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
try {
$this->setAttributeValue($object, $attribute, $value, $format, $context);
} catch (InvalidArgumentException $e) {
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e);
}
}
@ -233,7 +233,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*
* @return mixed
*
* @throws UnexpectedValueException
* @throws NotNormalizableValueException
* @throws LogicException
*/
private function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context)
@ -292,7 +292,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
return $data;
}
throw new UnexpectedValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data)));
throw new NotNormalizableValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data)));
}
/**

View File

@ -13,7 +13,7 @@ namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\BadMethodCallException;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerInterface;
@ -33,6 +33,8 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa
/**
* {@inheritdoc}
*
* @throws NotNormalizableValueException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
@ -52,7 +54,7 @@ class ArrayDenormalizer implements DenormalizerInterface, SerializerAwareInterfa
$builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
foreach ($data as $key => $value) {
if (null !== $builtinType && !call_user_func('is_'.$builtinType, $key)) {
throw new UnexpectedValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, gettype($key)));
throw new NotNormalizableValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, gettype($key)));
}
$data[$key] = $serializer->denormalize($value, $class, $format, $context);

View File

@ -15,7 +15,7 @@ use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
/**
* Normalizes an {@see \SplFileInfo} object to a data URI.
@ -85,11 +85,14 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
* Regex adapted from Brian Grinstead code.
*
* @see https://gist.github.com/bgrins/6194623
*
* @throws InvalidArgumentException
* @throws NotNormalizableValueException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
if (!preg_match('/^data:([a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}\/[a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}(;[a-z0-9\-]+\=[a-z0-9\-]+)?)?(;base64)?,[a-z0-9\!\$\&\\\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i', $data)) {
throw new UnexpectedValueException('The provided "data:" URI is not valid.');
throw new NotNormalizableValueException('The provided "data:" URI is not valid.');
}
try {
@ -102,7 +105,7 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface
return new \SplFileObject($data);
}
} catch (\RuntimeException $exception) {
throw new UnexpectedValueException($exception->getMessage(), $exception->getCode(), $exception);
throw new NotNormalizableValueException($exception->getMessage(), $exception->getCode(), $exception);
}
throw new InvalidArgumentException(sprintf('The class parameter "%s" is not supported. It must be one of "SplFileInfo", "SplFileObject" or "Symfony\Component\HttpFoundation\File\File".', $class));

View File

@ -12,7 +12,7 @@
namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
/**
* Normalizes an object implementing the {@see \DateTimeInterface} to a date string.
@ -79,7 +79,7 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
/**
* {@inheritdoc}
*
* @throws UnexpectedValueException
* @throws NotNormalizableValueException
*/
public function denormalize($data, $class, $format = null, array $context = array())
{
@ -100,7 +100,7 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
$dateTimeErrors = \DateTime::class === $class ? \DateTime::getLastErrors() : \DateTimeImmutable::getLastErrors();
throw new UnexpectedValueException(sprintf(
throw new NotNormalizableValueException(sprintf(
'Parsing datetime string "%s" using format "%s" resulted in %d errors:'."\n".'%s',
$data,
$dateTimeFormat,
@ -112,7 +112,7 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface
try {
return \DateTime::class === $class ? new \DateTime($data, $timezone) : new \DateTimeImmutable($data, $timezone);
} catch (\Exception $e) {
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e);
}
}

View File

@ -15,12 +15,13 @@ use Symfony\Component\Serializer\Encoder\ChainDecoder;
use Symfony\Component\Serializer\Encoder\ChainEncoder;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Serializer serializes and deserializes data.
@ -108,7 +109,7 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
final public function serialize($data, $format, array $context = array())
{
if (!$this->supportsEncoding($format)) {
throw new UnexpectedValueException(sprintf('Serialization for the format %s is not supported', $format));
throw new NotEncodableValueException(sprintf('Serialization for the format %s is not supported', $format));
}
if ($this->encoder->needsNormalization($format)) {
@ -124,7 +125,7 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
final public function deserialize($data, $type, $format, array $context = array())
{
if (!$this->supportsDecoding($format)) {
throw new UnexpectedValueException(sprintf('Deserialization for the format %s is not supported', $format));
throw new NotEncodableValueException(sprintf('Deserialization for the format %s is not supported', $format));
}
$data = $this->decode($data, $format, $context);
@ -160,14 +161,16 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
}
throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($data)));
throw new NotNormalizableValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($data)));
}
throw new UnexpectedValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true)));
throw new NotNormalizableValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true)));
}
/**
* {@inheritdoc}
*
* @throws NotNormalizableValueException
*/
public function denormalize($data, $type, $format = null, array $context = array())
{
@ -179,7 +182,7 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
return $normalizer->denormalize($data, $type, $format, $context);
}
throw new UnexpectedValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $type));
throw new NotNormalizableValueException(sprintf('Could not denormalize object of type %s, no supporting normalizer found.', $type));
}
/**