[Config] Improving the exception when a resource cannot be imported
This improves, for example, the exception one would receive if they tried to import a resource from a bundle that doesn't exist. Previously, the deep "bundle is not activated" exception would be thrown. That has value, however there is no indication of where the exception is actually occurring. In this new implementation, we throw an exception that explains exactly which resource, and from which source resource, cannot be loaded. The deeper exception is still thrown as a nested exception. Two caveats: * The `HttpKernel::varToString` method was replicated * This introduces a new `Exception` class, which allows us to prevent lot's of exceptions from nesting into each other in the case that some deeply imported resource cannot be imported (each upstream import that fails doesn't add its own exception).
This commit is contained in:
parent
65ac5ec7c0
commit
b9883a3bad
@ -0,0 +1,63 @@
|
|||||||
|
<?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\Config\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception class for when a resource cannot be imported.
|
||||||
|
*
|
||||||
|
* @author Ryan Weaver <ryan@thatsquality.com>
|
||||||
|
*/
|
||||||
|
class FileLoaderImportException extends \Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $resource The resource that could not be imported
|
||||||
|
* @param string $sourceResource The original resource importing the new resource
|
||||||
|
* @param integer $code The error code
|
||||||
|
* @param Exception $previous A previous exception
|
||||||
|
*/
|
||||||
|
public function __construct($resource, $sourceResource, $code = null, $previous = null)
|
||||||
|
{
|
||||||
|
if (null === $sourceResource) {
|
||||||
|
$message = sprintf('Cannot import resource "%s".', $this->varToString($resource));
|
||||||
|
} else {
|
||||||
|
$message = sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function varToString($var)
|
||||||
|
{
|
||||||
|
if (is_object($var)) {
|
||||||
|
return sprintf('[object](%s)', get_class($var));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($var)) {
|
||||||
|
$a = array();
|
||||||
|
foreach ($var as $k => $v) {
|
||||||
|
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf("[array](%s)", implode(', ', $a));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_resource($var)) {
|
||||||
|
return '[resource]';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $var) {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace("\n", '', var_export((string) $var, true));
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Config\Loader;
|
namespace Symfony\Component\Config\Loader;
|
||||||
|
|
||||||
use Symfony\Component\Config\FileLocatorInterface;
|
use Symfony\Component\Config\FileLocatorInterface;
|
||||||
|
use Symfony\Component\Config\Exception\FileLoaderImportException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FileLoader is the abstract class used by all built-in loaders that are file based.
|
* FileLoader is the abstract class used by all built-in loaders that are file based.
|
||||||
@ -51,7 +52,7 @@ abstract class FileLoader extends Loader
|
|||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function import($resource, $type = null, $ignoreErrors = false)
|
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$loader = $this->resolve($resource, $type);
|
$loader = $this->resolve($resource, $type);
|
||||||
@ -63,8 +64,13 @@ abstract class FileLoader extends Loader
|
|||||||
return $loader->load($resource);
|
return $loader->load($resource);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if (!$ignoreErrors) {
|
if (!$ignoreErrors) {
|
||||||
|
// prevent embedded imports from nesting multiple exceptions
|
||||||
|
if ($e instanceof FileLoaderImportException) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new FileLoaderImportException($resource, $sourceResource, null, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ class XmlFileLoader extends FileLoader
|
|||||||
|
|
||||||
foreach ($imports as $import) {
|
foreach ($imports as $import) {
|
||||||
$this->setCurrentDir(dirname($file));
|
$this->setCurrentDir(dirname($file));
|
||||||
$this->import((string) $import['resource'], null, (Boolean) $import->getAttributeAsPhp('ignore-errors'));
|
$this->import((string) $import['resource'], null, (Boolean) $import->getAttributeAsPhp('ignore-errors'), $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class YamlFileLoader extends FileLoader
|
|||||||
|
|
||||||
foreach ($content['imports'] as $import) {
|
foreach ($content['imports'] as $import) {
|
||||||
$this->setCurrentDir(dirname($file));
|
$this->setCurrentDir(dirname($file));
|
||||||
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (Boolean) $import['ignore_errors'] : false);
|
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (Boolean) $import['ignore_errors'] : false, $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class XmlFileLoader extends FileLoader
|
|||||||
$type = (string) $node->getAttribute('type');
|
$type = (string) $node->getAttribute('type');
|
||||||
$prefix = (string) $node->getAttribute('prefix');
|
$prefix = (string) $node->getAttribute('prefix');
|
||||||
$this->setCurrentDir(dirname($path));
|
$this->setCurrentDir(dirname($path));
|
||||||
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null)), $prefix);
|
$collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
|
throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName));
|
||||||
|
@ -64,7 +64,7 @@ class YamlFileLoader extends FileLoader
|
|||||||
$type = isset($config['type']) ? $config['type'] : null;
|
$type = isset($config['type']) ? $config['type'] : null;
|
||||||
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
|
$prefix = isset($config['prefix']) ? $config['prefix'] : null;
|
||||||
$this->setCurrentDir(dirname($path));
|
$this->setCurrentDir(dirname($path));
|
||||||
$collection->addCollection($this->import($config['resource'], $type), $prefix);
|
$collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix);
|
||||||
} elseif (isset($config['pattern'])) {
|
} elseif (isset($config['pattern'])) {
|
||||||
$this->parseRoute($collection, $name, $config, $path);
|
$this->parseRoute($collection, $name, $config, $path);
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user