feature #31398 [TwigBundle] Deprecating error templates for non-html formats and using ErrorRenderer as fallback (yceruto)
This PR was merged into the 4.4 branch.
Discussion
----------
[TwigBundle] Deprecating error templates for non-html formats and using ErrorRenderer as fallback
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
In the previous [PR](https://github.com/symfony/symfony/pull/31065) we created a new mechanism to render any PHP error/exception in a formatted string, which if the FB is enabled, would return an HTTP Response according to the preferred Request format (html, json, xml, txt, etc.), but when installing the TwigBundle this rendering mechanism is replaced by the current ExceptionController.
This ExceptionController allows us to render custom error pages based on Twig in many formats, just what is already supported with the new ErrorRenderer component, so let's deprecate this in favor of the native.
Commits
-------
bf0c24a634
Deprecating error templates for non-html formats and using ErrorRenderer
This commit is contained in:
commit
4045a134df
@ -151,6 +151,74 @@ TwigBridge
|
|||||||
|
|
||||||
* Deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the
|
* Deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the
|
||||||
`DebugCommand::__construct()` method, swap the variables position.
|
`DebugCommand::__construct()` method, swap the variables position.
|
||||||
|
|
||||||
|
TwigBundle
|
||||||
|
----------
|
||||||
|
|
||||||
|
* Deprecated default value `twig.controller.exception::showAction` of the `twig.exception_controller` configuration option,
|
||||||
|
set it to `null` instead. This will also change the default error response format according to https://tools.ietf.org/html/rfc7807
|
||||||
|
for `json`, `xml`, `atom` and `txt` formats:
|
||||||
|
|
||||||
|
Before:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": {
|
||||||
|
"code": 404,
|
||||||
|
"message": "Sorry, the page you are looking for could not be found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "Not Found",
|
||||||
|
"status": 404,
|
||||||
|
"detail": "Sorry, the page you are looking for could not be found"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Deprecated the `ExceptionController` and all built-in error templates, use the error renderer mechanism of the `ErrorRenderer` component
|
||||||
|
* Deprecated loading custom error templates in non-html formats. Custom HTML error pages based on Twig keep working as before:
|
||||||
|
|
||||||
|
Before (`templates/bundles/TwigBundle/Exception/error.jsonld.twig`):
|
||||||
|
```twig
|
||||||
|
{
|
||||||
|
"@id": "https://example.com",
|
||||||
|
"@type": "error",
|
||||||
|
"@context": {
|
||||||
|
"title": "{{ status_text }}",
|
||||||
|
"code": {{ status_code }},
|
||||||
|
"message": "{{ exception.message }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
After (`App\ErrorRenderer\JsonLdErrorRenderer`):
|
||||||
|
```php
|
||||||
|
class JsonLdErrorRenderer implements ErrorRendererInterface
|
||||||
|
{
|
||||||
|
public static function getFormat(): string
|
||||||
|
{
|
||||||
|
return 'jsonld';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(FlattenException $exception): string
|
||||||
|
{
|
||||||
|
return json_encode([
|
||||||
|
'@id' => 'https://example.com',
|
||||||
|
'@type' => 'error',
|
||||||
|
'@context' => [
|
||||||
|
'title' => $exception->getTitle(),
|
||||||
|
'code' => $exception->getStatusCode(),
|
||||||
|
'message' => $exception->getMessage(),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure your rendering service tagging it with `error_renderer.renderer`.
|
||||||
|
|
||||||
Validator
|
Validator
|
||||||
---------
|
---------
|
||||||
|
@ -467,6 +467,8 @@ TwigBundle
|
|||||||
* The default value (`false`) of the `twig.strict_variables` configuration option has been changed to `%kernel.debug%`.
|
* The default value (`false`) of the `twig.strict_variables` configuration option has been changed to `%kernel.debug%`.
|
||||||
* The `transchoice` tag and filter have been removed, use the `trans` ones instead with a `%count%` parameter.
|
* The `transchoice` tag and filter have been removed, use the `trans` ones instead with a `%count%` parameter.
|
||||||
* Removed support for legacy templates directories `src/Resources/views/` and `src/Resources/<BundleName>/views/`, use `templates/` and `templates/bundles/<BundleName>/` instead.
|
* Removed support for legacy templates directories `src/Resources/views/` and `src/Resources/<BundleName>/views/`, use `templates/` and `templates/bundles/<BundleName>/` instead.
|
||||||
|
* The default value (`twig.controller.exception::showAction`) of the `twig.exception_controller` configuration option has been changed to `null`.
|
||||||
|
* Removed `ExceptionController` class and all built-in error templates
|
||||||
|
|
||||||
TwigBridge
|
TwigBridge
|
||||||
----------
|
----------
|
||||||
|
@ -7,3 +7,4 @@ framework:
|
|||||||
|
|
||||||
twig:
|
twig:
|
||||||
strict_variables: '%kernel.debug%'
|
strict_variables: '%kernel.debug%'
|
||||||
|
exception_controller: ~
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
"symfony/stopwatch": "^3.4|^4.0|^5.0",
|
"symfony/stopwatch": "^3.4|^4.0|^5.0",
|
||||||
"symfony/translation": "^4.3|^5.0",
|
"symfony/translation": "^4.3|^5.0",
|
||||||
"symfony/templating": "^3.4|^4.0|^5.0",
|
"symfony/templating": "^3.4|^4.0|^5.0",
|
||||||
"symfony/twig-bundle": "^3.4|^4.0|^5.0",
|
"symfony/twig-bundle": "^4.4|^5.0",
|
||||||
"symfony/validator": "^4.1|^5.0",
|
"symfony/validator": "^4.1|^5.0",
|
||||||
"symfony/var-dumper": "^4.3|^5.0",
|
"symfony/var-dumper": "^4.3|^5.0",
|
||||||
"symfony/workflow": "^4.3|^5.0",
|
"symfony/workflow": "^4.3|^5.0",
|
||||||
@ -80,6 +80,7 @@
|
|||||||
"symfony/stopwatch": "<3.4",
|
"symfony/stopwatch": "<3.4",
|
||||||
"symfony/translation": "<4.3",
|
"symfony/translation": "<4.3",
|
||||||
"symfony/twig-bridge": "<4.1.1",
|
"symfony/twig-bridge": "<4.1.1",
|
||||||
|
"symfony/twig-bundle": "<4.4",
|
||||||
"symfony/validator": "<4.1",
|
"symfony/validator": "<4.1",
|
||||||
"symfony/workflow": "<4.3"
|
"symfony/workflow": "<4.3"
|
||||||
},
|
},
|
||||||
|
@ -70,6 +70,6 @@ class JsonLoginTest extends AbstractWebTestCase
|
|||||||
|
|
||||||
$this->assertSame(400, $response->getStatusCode());
|
$this->assertSame(400, $response->getStatusCode());
|
||||||
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
$this->assertSame('application/json', $response->headers->get('Content-Type'));
|
||||||
$this->assertArraySubset(['error' => ['code' => 400, 'message' => 'Bad Request']], json_decode($response->getContent(), true));
|
$this->assertArraySubset(['title' => 'Bad Request', 'status' => 400, 'detail' => 'Invalid JSON.'], json_decode($response->getContent(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
<?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\Bundle\SecurityBundle\Tests\Functional\app;
|
||||||
|
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\JsonErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class ExceptionController
|
||||||
|
{
|
||||||
|
private $errorRenderer;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->errorRenderer = new ErrorRenderer([
|
||||||
|
new HtmlErrorRenderer(),
|
||||||
|
new JsonErrorRenderer(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(Request $request, FlattenException $exception)
|
||||||
|
{
|
||||||
|
return new Response($this->errorRenderer->render($exception, $request->getPreferredFormat()), $exception->getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
@ -12,5 +12,4 @@
|
|||||||
return [
|
return [
|
||||||
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
|
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
|
||||||
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||||
new Symfony\Bundle\TwigBundle\TwigBundle(),
|
|
||||||
];
|
];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
imports:
|
imports:
|
||||||
- { resource: ./../config/default.yml }
|
- { resource: ./../config/framework.yml }
|
||||||
services:
|
services:
|
||||||
Symfony\Component\Ldap\Ldap:
|
Symfony\Component\Ldap\Ldap:
|
||||||
arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
|
arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
|
||||||
|
@ -11,10 +11,8 @@
|
|||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
||||||
use Symfony\Bundle\TwigBundle\TwigBundle;
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new FrameworkBundle(),
|
new FrameworkBundle(),
|
||||||
new SecurityBundle(),
|
new SecurityBundle(),
|
||||||
new TwigBundle(),
|
|
||||||
];
|
];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
imports:
|
imports:
|
||||||
- { resource: ./../config/default.yml }
|
- { resource: ./../config/framework.yml }
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# alias the service so we can access it in the tests
|
# alias the service so we can access it in the tests
|
||||||
|
@ -2,3 +2,4 @@
|
|||||||
twig:
|
twig:
|
||||||
debug: '%kernel.debug%'
|
debug: '%kernel.debug%'
|
||||||
strict_variables: '%kernel.debug%'
|
strict_variables: '%kernel.debug%'
|
||||||
|
exception_controller: Symfony\Bundle\SecurityBundle\Tests\Functional\app\ExceptionController
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
"symfony/config": "^4.2|^5.0",
|
"symfony/config": "^4.2|^5.0",
|
||||||
"symfony/dependency-injection": "^4.2|^5.0",
|
"symfony/dependency-injection": "^4.2|^5.0",
|
||||||
"symfony/http-kernel": "^4.3",
|
"symfony/http-kernel": "^4.4",
|
||||||
"symfony/security-core": "^4.3",
|
"symfony/security-core": "^4.3",
|
||||||
"symfony/security-csrf": "^4.2|^5.0",
|
"symfony/security-csrf": "^4.2|^5.0",
|
||||||
"symfony/security-guard": "^4.2|^5.0",
|
"symfony/security-guard": "^4.2|^5.0",
|
||||||
@ -33,10 +33,10 @@
|
|||||||
"symfony/css-selector": "^3.4|^4.0|^5.0",
|
"symfony/css-selector": "^3.4|^4.0|^5.0",
|
||||||
"symfony/dom-crawler": "^3.4|^4.0|^5.0",
|
"symfony/dom-crawler": "^3.4|^4.0|^5.0",
|
||||||
"symfony/form": "^3.4|^4.0|^5.0",
|
"symfony/form": "^3.4|^4.0|^5.0",
|
||||||
"symfony/framework-bundle": "^4.2|^5.0",
|
"symfony/framework-bundle": "^4.4|^5.0",
|
||||||
"symfony/http-foundation": "^3.4|^4.0|^5.0",
|
"symfony/http-foundation": "^3.4|^4.0|^5.0",
|
||||||
"symfony/translation": "^3.4|^4.0|^5.0",
|
"symfony/translation": "^3.4|^4.0|^5.0",
|
||||||
"symfony/twig-bundle": "^4.2|^5.0",
|
"symfony/twig-bundle": "^4.4|^5.0",
|
||||||
"symfony/twig-bridge": "^3.4|^4.0|^5.0",
|
"symfony/twig-bridge": "^3.4|^4.0|^5.0",
|
||||||
"symfony/process": "^3.4|^4.0|^5.0",
|
"symfony/process": "^3.4|^4.0|^5.0",
|
||||||
"symfony/validator": "^3.4|^4.0|^5.0",
|
"symfony/validator": "^3.4|^4.0|^5.0",
|
||||||
@ -48,9 +48,9 @@
|
|||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/browser-kit": "<4.2",
|
"symfony/browser-kit": "<4.2",
|
||||||
"symfony/twig-bundle": "<4.2",
|
"symfony/twig-bundle": "<4.4",
|
||||||
"symfony/var-dumper": "<3.4",
|
"symfony/var-dumper": "<3.4",
|
||||||
"symfony/framework-bundle": "<4.2",
|
"symfony/framework-bundle": "<4.4",
|
||||||
"symfony/console": "<3.4"
|
"symfony/console": "<3.4"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -6,6 +6,9 @@ CHANGELOG
|
|||||||
|
|
||||||
* marked the `TemplateIterator` as `internal`
|
* marked the `TemplateIterator` as `internal`
|
||||||
* added HTML comment to beginning and end of `exception_full.html.twig`
|
* added HTML comment to beginning and end of `exception_full.html.twig`
|
||||||
|
* added a new `TwigHtmlErrorRenderer` for `html` format, integrated with the `ErrorRenderer` component
|
||||||
|
* deprecated `ExceptionController` class and all built-in error templates in favor of the new error renderer mechanism
|
||||||
|
* deprecated default value `twig.controller.exception::showAction` of `twig.exception_controller` configuration option, set it to `null` instead
|
||||||
|
|
||||||
4.2.0
|
4.2.0
|
||||||
-----
|
-----
|
||||||
|
@ -19,12 +19,16 @@ use Twig\Environment;
|
|||||||
use Twig\Error\LoaderError;
|
use Twig\Error\LoaderError;
|
||||||
use Twig\Loader\ExistsLoaderInterface;
|
use Twig\Loader\ExistsLoaderInterface;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use the ErrorRenderer component instead.', ExceptionController::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExceptionController renders error or exception pages for a given
|
* ExceptionController renders error or exception pages for a given
|
||||||
* FlattenException.
|
* FlattenException.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Matthias Pigulla <mp@webfactory.de>
|
* @author Matthias Pigulla <mp@webfactory.de>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.4, use the ErrorRenderer component instead.
|
||||||
*/
|
*/
|
||||||
class ExceptionController
|
class ExceptionController
|
||||||
{
|
{
|
||||||
|
@ -11,8 +11,10 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\TwigBundle\Controller;
|
namespace Symfony\Bundle\TwigBundle\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer;
|
||||||
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
|
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,16 +28,22 @@ class PreviewErrorController
|
|||||||
{
|
{
|
||||||
protected $kernel;
|
protected $kernel;
|
||||||
protected $controller;
|
protected $controller;
|
||||||
|
private $errorRenderer;
|
||||||
|
|
||||||
public function __construct(HttpKernelInterface $kernel, $controller)
|
public function __construct(HttpKernelInterface $kernel, $controller, ErrorRenderer $errorRenderer = null)
|
||||||
{
|
{
|
||||||
$this->kernel = $kernel;
|
$this->kernel = $kernel;
|
||||||
$this->controller = $controller;
|
$this->controller = $controller;
|
||||||
|
$this->errorRenderer = $errorRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function previewErrorPageAction(Request $request, $code)
|
public function previewErrorPageAction(Request $request, $code)
|
||||||
{
|
{
|
||||||
$exception = FlattenException::createFromThrowable(new \Exception('Something has intentionally gone wrong.'), $code);
|
$exception = FlattenException::createFromThrowable(new \Exception('Something has intentionally gone wrong.'), $code, ['X-Debug' => false]);
|
||||||
|
|
||||||
|
if (null === $this->controller && null !== $this->errorRenderer) {
|
||||||
|
return new Response($this->errorRenderer->render($exception, $request->getPreferredFormat()), $code);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This Request mimics the parameters set by
|
* This Request mimics the parameters set by
|
||||||
|
@ -34,7 +34,13 @@ class Configuration implements ConfigurationInterface
|
|||||||
|
|
||||||
$rootNode
|
$rootNode
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('exception_controller')->defaultValue('twig.controller.exception::showAction')->end()
|
->scalarNode('exception_controller')
|
||||||
|
->defaultValue(static function () {
|
||||||
|
@trigger_error('Relying on the default value ("twig.controller.exception::showAction") of the "twig.exception_controller" configuration option is deprecated since Symfony 4.4, set it to "null" explicitly instead, which will be the new default in 5.0.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
return 'twig.controller.exception::showAction';
|
||||||
|
})
|
||||||
|
->end()
|
||||||
->end()
|
->end()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
<?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\Bundle\TwigBundle\ErrorRenderer;
|
||||||
|
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\ErrorRendererInterface;
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
|
||||||
|
use Twig\Environment;
|
||||||
|
use Twig\Error\LoaderError;
|
||||||
|
use Twig\Loader\ExistsLoaderInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the ability to render custom Twig-based HTML error pages
|
||||||
|
* in non-debug mode, otherwise falls back to HtmlErrorRenderer.
|
||||||
|
*
|
||||||
|
* @author Yonel Ceruto <yonelceruto@gmail.com>
|
||||||
|
*/
|
||||||
|
class TwigHtmlErrorRenderer implements ErrorRendererInterface
|
||||||
|
{
|
||||||
|
private $twig;
|
||||||
|
private $htmlErrorRenderer;
|
||||||
|
private $debug;
|
||||||
|
|
||||||
|
public function __construct(Environment $twig, HtmlErrorRenderer $htmlErrorRenderer, bool $debug = false)
|
||||||
|
{
|
||||||
|
$this->twig = $twig;
|
||||||
|
$this->htmlErrorRenderer = $htmlErrorRenderer;
|
||||||
|
$this->debug = $debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function getFormat(): string
|
||||||
|
{
|
||||||
|
return 'html';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function render(FlattenException $exception): string
|
||||||
|
{
|
||||||
|
$debug = $this->debug && ($exception->getHeaders()['X-Debug'] ?? true);
|
||||||
|
|
||||||
|
if ($debug) {
|
||||||
|
return $this->htmlErrorRenderer->render($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = $this->findTemplate($exception->getStatusCode());
|
||||||
|
|
||||||
|
if (null === $template) {
|
||||||
|
return $this->htmlErrorRenderer->render($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->twig->render($template, [
|
||||||
|
'legacy' => false, // to be removed in 5.0
|
||||||
|
'exception' => $exception,
|
||||||
|
'status_code' => $exception->getStatusCode(),
|
||||||
|
'status_text' => $exception->getTitle(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function findTemplate(int $statusCode): ?string
|
||||||
|
{
|
||||||
|
$template = sprintf('@Twig/Exception/error%s.html.twig', $statusCode);
|
||||||
|
if ($this->templateExists($template)) {
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = '@Twig/Exception/error.html.twig';
|
||||||
|
if ($this->templateExists($template)) {
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be removed in 5.0.
|
||||||
|
*
|
||||||
|
* Use instead:
|
||||||
|
*
|
||||||
|
* $this->twig->getLoader()->exists($template)
|
||||||
|
*/
|
||||||
|
private function templateExists(string $template): bool
|
||||||
|
{
|
||||||
|
$loader = $this->twig->getLoader();
|
||||||
|
if ($loader instanceof ExistsLoaderInterface || method_exists($loader, 'exists')) {
|
||||||
|
return $loader->exists($template);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$loader->getSourceContext($template);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (LoaderError $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -139,11 +139,13 @@
|
|||||||
<service id="twig.controller.exception" class="Symfony\Bundle\TwigBundle\Controller\ExceptionController" public="true">
|
<service id="twig.controller.exception" class="Symfony\Bundle\TwigBundle\Controller\ExceptionController" public="true">
|
||||||
<argument type="service" id="twig" />
|
<argument type="service" id="twig" />
|
||||||
<argument>%kernel.debug%</argument>
|
<argument>%kernel.debug%</argument>
|
||||||
|
<deprecated>The "%service_id%" service is deprecated since Symfony 4.4.</deprecated>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="twig.controller.preview_error" class="Symfony\Bundle\TwigBundle\Controller\PreviewErrorController" public="true">
|
<service id="twig.controller.preview_error" class="Symfony\Bundle\TwigBundle\Controller\PreviewErrorController" public="true">
|
||||||
<argument type="service" id="http_kernel" />
|
<argument type="service" id="http_kernel" />
|
||||||
<argument>%twig.exception_listener.controller%</argument>
|
<argument>%twig.exception_listener.controller%</argument>
|
||||||
|
<argument type="service" id="error_renderer" on-invalid="null" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="twig.configurator.environment" class="Symfony\Bundle\TwigBundle\DependencyInjection\Configurator\EnvironmentConfigurator">
|
<service id="twig.configurator.environment" class="Symfony\Bundle\TwigBundle\DependencyInjection\Configurator\EnvironmentConfigurator">
|
||||||
@ -158,5 +160,12 @@
|
|||||||
<service id="twig.runtime_loader" class="Twig\RuntimeLoader\ContainerRuntimeLoader">
|
<service id="twig.runtime_loader" class="Twig\RuntimeLoader\ContainerRuntimeLoader">
|
||||||
<argument /> <!-- runtime locator -->
|
<argument /> <!-- runtime locator -->
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="twig.error_renderer.html" class="Symfony\Bundle\TwigBundle\ErrorRenderer\TwigHtmlErrorRenderer">
|
||||||
|
<tag name="error_renderer.renderer" priority="1" />
|
||||||
|
<argument type="service" id="twig" />
|
||||||
|
<argument type="service" id="error_renderer.renderer.html" />
|
||||||
|
<argument>%kernel.debug%</argument>
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ include('@Twig/Exception/error.xml.twig') }}
|
{{ include('@Twig/Exception/error.xml.twig') }}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
/*
|
/*
|
||||||
{{ status_code }} {{ status_text }}
|
{{ status_code }} {{ status_text }}
|
||||||
|
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
{% if legacy is not defined or legacy %}
|
||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
|
{% endif %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
/*
|
/*
|
||||||
{{ status_code }} {{ status_text }}
|
{{ status_code }} {{ status_text }}
|
||||||
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ { 'error': { 'code': status_code, 'message': status_text } }|json_encode|raw }}
|
{{ { 'error': { 'code': status_code, 'message': status_text } }|json_encode|raw }}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ include('@Twig/Exception/error.xml.twig') }}
|
{{ include('@Twig/Exception/error.xml.twig') }}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
Oops! An Error Occurred
|
Oops! An Error Occurred
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
<?xml version="1.0" encoding="{{ _charset }}" ?>
|
<?xml version="1.0" encoding="{{ _charset }}" ?>
|
||||||
|
|
||||||
<error code="{{ status_code }}" message="{{ status_text }}" />
|
<error code="{{ status_code }}" message="{{ status_text }}" />
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ include('@Twig/Exception/exception.xml.twig', { exception: exception }) }}
|
{{ include('@Twig/Exception/exception.xml.twig', { exception: exception }) }}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
/*
|
/*
|
||||||
{{ include('@Twig/Exception/exception.txt.twig', { exception: exception }) }}
|
{{ include('@Twig/Exception/exception.txt.twig', { exception: exception }) }}
|
||||||
*/
|
*/
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
/*
|
/*
|
||||||
{{ include('@Twig/Exception/exception.txt.twig', { exception: exception }) }}
|
{{ include('@Twig/Exception/exception.txt.twig', { exception: exception }) }}
|
||||||
*/
|
*/
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ { 'error': { 'code': status_code, 'message': status_text, 'exception': exception.toarray } }|json_encode|raw }}
|
{{ { 'error': { 'code': status_code, 'message': status_text, 'exception': exception.toarray } }|json_encode|raw }}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{{ include('@Twig/Exception/exception.xml.twig', { exception: exception }) }}
|
{{ include('@Twig/Exception/exception.xml.twig', { exception: exception }) }}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
[exception] {{ status_code ~ ' | ' ~ status_text ~ ' | ' ~ exception.class }}
|
[exception] {{ status_code ~ ' | ' ~ status_text ~ ' | ' ~ exception.class }}
|
||||||
[message] {{ exception.message }}
|
[message] {{ exception.message }}
|
||||||
{% for i, e in exception.toarray %}
|
{% for i, e in exception.toarray %}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
<?xml version="1.0" encoding="{{ _charset }}" ?>
|
<?xml version="1.0" encoding="{{ _charset }}" ?>
|
||||||
|
|
||||||
<error code="{{ status_code }}" message="{{ status_text }}">
|
<error code="{{ status_code }}" message="{{ status_text }}">
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
<traces>
|
<traces>
|
||||||
{% for trace in exception.trace %}
|
{% for trace in exception.trace %}
|
||||||
<trace>
|
<trace>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{# This file is based on WebProfilerBundle/Resources/views/Profiler/base_js.html.twig.
|
{# This file is based on WebProfilerBundle/Resources/views/Profiler/base_js.html.twig.
|
||||||
If you make any change in this file, verify the same change is needed in the other file. #}
|
If you make any change in this file, verify the same change is needed in the other file. #}
|
||||||
<script{% if csp_script_nonce is defined and csp_script_nonce %} nonce="{{ csp_script_nonce }}"{% endif %}>/*<![CDATA[*/
|
<script{% if csp_script_nonce is defined and csp_script_nonce %} nonce="{{ csp_script_nonce }}"{% endif %}>/*<![CDATA[*/
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{# This file is based on WebProfilerBundle/Resources/views/Profiler/profiler.css.twig.
|
{# This file is based on WebProfilerBundle/Resources/views/Profiler/profiler.css.twig.
|
||||||
If you make any change in this file, verify the same change is needed in the other file. #}
|
If you make any change in this file, verify the same change is needed in the other file. #}
|
||||||
:root {
|
:root {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
{% deprecated 'The template "' ~ _self ~'" is deprecated since Symfony 4.4, will be removed in 5.0.' %}
|
||||||
{% block before_html %}{% endblock %}
|
{% block before_html %}{% endblock %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -18,6 +18,9 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
use Twig\Loader\ArrayLoader;
|
use Twig\Loader\ArrayLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class ExceptionControllerTest extends TestCase
|
class ExceptionControllerTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testShowActionCanBeForcedToShowErrorPage()
|
public function testShowActionCanBeForcedToShowErrorPage()
|
||||||
|
@ -21,6 +21,7 @@ class ConfigurationTest extends TestCase
|
|||||||
{
|
{
|
||||||
$input = [
|
$input = [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
'form_themes' => ['form_div_layout.html.twig'],
|
'form_themes' => ['form_div_layout.html.twig'],
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -42,10 +43,23 @@ class ConfigurationTest extends TestCase
|
|||||||
$this->assertFalse($config['strict_variables']);
|
$this->assertFalse($config['strict_variables']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Relying on the default value ("twig.controller.exception::showAction") of the "twig.exception_controller" configuration option is deprecated since Symfony 4.4, set it to "null" explicitly instead, which will be the new default in 5.0.
|
||||||
|
*/
|
||||||
|
public function testGetExceptionControllerDefault()
|
||||||
|
{
|
||||||
|
$processor = new Processor();
|
||||||
|
$config = $processor->processConfiguration(new Configuration(), [[]]);
|
||||||
|
|
||||||
|
$this->assertSame('twig.controller.exception::showAction', $config['exception_controller']);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGlobalsAreNotNormalized()
|
public function testGlobalsAreNotNormalized()
|
||||||
{
|
{
|
||||||
$input = [
|
$input = [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
'globals' => ['some-global' => true],
|
'globals' => ['some-global' => true],
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -59,6 +73,7 @@ class ConfigurationTest extends TestCase
|
|||||||
{
|
{
|
||||||
$input = [
|
$input = [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
'globals' => ['global' => ['some-key' => 'some-value']],
|
'globals' => ['global' => ['some-key' => 'some-value']],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -4,4 +4,5 @@ $container->loadFromExtension('twig', [
|
|||||||
'autoescape_service' => 'my_project.some_bundle.template_escaping_guesser',
|
'autoescape_service' => 'my_project.some_bundle.template_escaping_guesser',
|
||||||
'autoescape_service_method' => 'guess',
|
'autoescape_service_method' => 'guess',
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
$container->loadFromExtension('twig', [
|
$container->loadFromExtension('twig', [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
|
@ -12,4 +12,5 @@ $container->loadFromExtension('twig', [
|
|||||||
'thousands_separator' => '.',
|
'thousands_separator' => '.',
|
||||||
],
|
],
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
|
@ -17,6 +17,7 @@ $container->loadFromExtension('twig', [
|
|||||||
'charset' => 'ISO-8859-1',
|
'charset' => 'ISO-8859-1',
|
||||||
'debug' => true,
|
'debug' => true,
|
||||||
'strict_variables' => true,
|
'strict_variables' => true,
|
||||||
|
'exception_controller' => null,
|
||||||
'default_path' => '%kernel.project_dir%/Fixtures/templates',
|
'default_path' => '%kernel.project_dir%/Fixtures/templates',
|
||||||
'paths' => [
|
'paths' => [
|
||||||
'path1',
|
'path1',
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
||||||
|
|
||||||
<twig:config autoescape-service="my_project.some_bundle.template_escaping_guesser" autoescape-service-method="guess" strict-variables="false" />
|
<twig:config autoescape-service="my_project.some_bundle.template_escaping_guesser" autoescape-service-method="guess" strict-variables="false" exception-controller="null" />
|
||||||
</container>
|
</container>
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
||||||
|
|
||||||
<twig:config strict-variables="false" />
|
<twig:config strict-variables="false" exception-controller="null" />
|
||||||
</container>
|
</container>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
||||||
|
|
||||||
<twig:config auto-reload="true" autoescape="true" base-template-class="stdClass" cache="/tmp" charset="ISO-8859-1" debug="true" strict-variables="true">
|
<twig:config auto-reload="true" autoescape="true" base-template-class="stdClass" cache="/tmp" charset="ISO-8859-1" debug="true" strict-variables="true" exception-controller="null">
|
||||||
<twig:path namespace="namespace3">namespaced_path3</twig:path>
|
<twig:path namespace="namespace3">namespaced_path3</twig:path>
|
||||||
</twig:config>
|
</twig:config>
|
||||||
</container>
|
</container>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
||||||
|
|
||||||
<twig:config strict-variables="false">
|
<twig:config strict-variables="false" exception-controller="null">
|
||||||
<twig:date format="Y-m-d" interval-format="%d" timezone="Europe/Berlin" />
|
<twig:date format="Y-m-d" interval-format="%d" timezone="Europe/Berlin" />
|
||||||
<twig:number-format decimals="2" decimal-point="," thousands-separator="." />
|
<twig:number-format decimals="2" decimal-point="," thousands-separator="." />
|
||||||
</twig:config>
|
</twig:config>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
|
||||||
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
http://symfony.com/schema/dic/twig https://symfony.com/schema/dic/twig/twig-1.0.xsd">
|
||||||
|
|
||||||
<twig:config auto-reload="true" autoescape="true" base-template-class="stdClass" cache="/tmp" charset="ISO-8859-1" debug="true" strict-variables="true" default-path="%kernel.project_dir%/Fixtures/templates">
|
<twig:config auto-reload="true" autoescape="true" base-template-class="stdClass" cache="/tmp" charset="ISO-8859-1" debug="true" strict-variables="true" default-path="%kernel.project_dir%/Fixtures/templates" exception-controller="null">
|
||||||
<twig:form-theme>MyBundle::form.html.twig</twig:form-theme>
|
<twig:form-theme>MyBundle::form.html.twig</twig:form-theme>
|
||||||
<twig:global key="foo" id="bar" type="service" />
|
<twig:global key="foo" id="bar" type="service" />
|
||||||
<twig:global key="baz">@@qux</twig:global>
|
<twig:global key="baz">@@qux</twig:global>
|
||||||
|
@ -2,3 +2,4 @@ twig:
|
|||||||
autoescape_service: my_project.some_bundle.template_escaping_guesser
|
autoescape_service: my_project.some_bundle.template_escaping_guesser
|
||||||
autoescape_service_method: guess
|
autoescape_service_method: guess
|
||||||
strict_variables: false # to be removed in 5.0 relying on default
|
strict_variables: false # to be removed in 5.0 relying on default
|
||||||
|
exception_controller: ~ # to be removed in 5.0 relying on default
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
twig:
|
twig:
|
||||||
strict_variables: false # to be removed in 5.0 relying on default
|
strict_variables: false # to be removed in 5.0 relying on default
|
||||||
|
exception_controller: ~ # to be removed in 5.0 relying on default
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
twig:
|
twig:
|
||||||
strict_variables: false # to be removed in 5.0 relying on default
|
strict_variables: false # to be removed in 5.0 relying on default
|
||||||
|
exception_controller: ~ # to be removed in 5.0 relying on default
|
||||||
paths:
|
paths:
|
||||||
namespaced_path3: namespace3
|
namespaced_path3: namespace3
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
twig:
|
twig:
|
||||||
strict_variables: false # to be removed in 5.0 relying on default
|
strict_variables: false # to be removed in 5.0 relying on default
|
||||||
|
exception_controller: ~ # to be removed in 5.0 relying on default
|
||||||
date:
|
date:
|
||||||
format: Y-m-d
|
format: Y-m-d
|
||||||
interval_format: '%d'
|
interval_format: '%d'
|
||||||
|
@ -14,6 +14,7 @@ twig:
|
|||||||
debug: true
|
debug: true
|
||||||
strict_variables: true
|
strict_variables: true
|
||||||
default_path: '%kernel.project_dir%/Fixtures/templates'
|
default_path: '%kernel.project_dir%/Fixtures/templates'
|
||||||
|
exception_controller: ~ # to be removed in 5.0 relying on default
|
||||||
paths:
|
paths:
|
||||||
path1: ''
|
path1: ''
|
||||||
path2: ''
|
path2: ''
|
||||||
|
@ -31,6 +31,7 @@ class TwigExtensionTest extends TestCase
|
|||||||
$container->registerExtension(new TwigExtension());
|
$container->registerExtension(new TwigExtension());
|
||||||
$container->loadFromExtension('twig', [
|
$container->loadFromExtension('twig', [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
$this->compileContainer($container);
|
$this->compileContainer($container);
|
||||||
|
|
||||||
@ -156,6 +157,7 @@ class TwigExtensionTest extends TestCase
|
|||||||
$container->loadFromExtension('twig', [
|
$container->loadFromExtension('twig', [
|
||||||
'globals' => $globals,
|
'globals' => $globals,
|
||||||
'strict_variables' => false, // // to be removed in 5.0 relying on default
|
'strict_variables' => false, // // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
$this->compileContainer($container);
|
$this->compileContainer($container);
|
||||||
|
|
||||||
@ -259,6 +261,7 @@ class TwigExtensionTest extends TestCase
|
|||||||
$container->registerExtension(new TwigExtension());
|
$container->registerExtension(new TwigExtension());
|
||||||
$container->loadFromExtension('twig', [
|
$container->loadFromExtension('twig', [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
$container->setAlias('test.twig.extension.debug.stopwatch', 'twig.extension.debug.stopwatch')->setPublic(true);
|
$container->setAlias('test.twig.extension.debug.stopwatch', 'twig.extension.debug.stopwatch')->setPublic(true);
|
||||||
$this->compileContainer($container);
|
$this->compileContainer($container);
|
||||||
@ -289,6 +292,7 @@ class TwigExtensionTest extends TestCase
|
|||||||
$container->registerExtension(new TwigExtension());
|
$container->registerExtension(new TwigExtension());
|
||||||
$container->loadFromExtension('twig', [
|
$container->loadFromExtension('twig', [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
]);
|
]);
|
||||||
$container->setParameter('kernel.environment', 'test');
|
$container->setParameter('kernel.environment', 'test');
|
||||||
$container->setParameter('debug.file_link_format', 'test');
|
$container->setParameter('debug.file_link_format', 'test');
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
<?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\Bundle\TwigBundle\Tests\ErrorRenderer;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bundle\TwigBundle\ErrorRenderer\TwigHtmlErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer\HtmlErrorRenderer;
|
||||||
|
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Twig\Environment;
|
||||||
|
use Twig\Loader\ArrayLoader;
|
||||||
|
|
||||||
|
class TwigHtmlErrorRendererTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testFallbackToNativeRendererIfDebugOn()
|
||||||
|
{
|
||||||
|
$exception = FlattenException::createFromThrowable(new \Exception());
|
||||||
|
|
||||||
|
$twig = $this->createMock(Environment::class);
|
||||||
|
$nativeRenderer = $this->createMock(HtmlErrorRenderer::class);
|
||||||
|
$nativeRenderer
|
||||||
|
->expects($this->once())
|
||||||
|
->method('render')
|
||||||
|
->with($exception)
|
||||||
|
;
|
||||||
|
|
||||||
|
(new TwigHtmlErrorRenderer($twig, $nativeRenderer, true))->render($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFallbackToNativeRendererIfCustomTemplateNotFound()
|
||||||
|
{
|
||||||
|
$exception = FlattenException::createFromThrowable(new NotFoundHttpException());
|
||||||
|
|
||||||
|
$twig = new Environment(new ArrayLoader([]));
|
||||||
|
|
||||||
|
$nativeRenderer = $this->createMock(HtmlErrorRenderer::class);
|
||||||
|
$nativeRenderer
|
||||||
|
->expects($this->once())
|
||||||
|
->method('render')
|
||||||
|
->with($exception)
|
||||||
|
;
|
||||||
|
|
||||||
|
(new TwigHtmlErrorRenderer($twig, $nativeRenderer, false))->render($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRenderCustomErrorTemplate()
|
||||||
|
{
|
||||||
|
$exception = FlattenException::createFromThrowable(new NotFoundHttpException());
|
||||||
|
|
||||||
|
$twig = new Environment(new ArrayLoader([
|
||||||
|
'@Twig/Exception/error404.html.twig' => '<h1>Page Not Found</h1>',
|
||||||
|
]));
|
||||||
|
|
||||||
|
$nativeRenderer = $this->createMock(HtmlErrorRenderer::class);
|
||||||
|
$nativeRenderer
|
||||||
|
->expects($this->never())
|
||||||
|
->method('render')
|
||||||
|
;
|
||||||
|
|
||||||
|
$content = (new TwigHtmlErrorRenderer($twig, $nativeRenderer, false))->render($exception);
|
||||||
|
|
||||||
|
$this->assertSame('<h1>Page Not Found</h1>', $content);
|
||||||
|
}
|
||||||
|
}
|
@ -99,6 +99,7 @@ class CacheWarmingKernel extends Kernel
|
|||||||
])
|
])
|
||||||
->loadFromExtension('twig', [ // to be removed in 5.0 relying on default
|
->loadFromExtension('twig', [ // to be removed in 5.0 relying on default
|
||||||
'strict_variables' => false,
|
'strict_variables' => false,
|
||||||
|
'exception_controller' => null,
|
||||||
])
|
])
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Bundle\TwigBundle\Tests\Functional;
|
|||||||
use Symfony\Bundle\TwigBundle\Tests\TestCase;
|
use Symfony\Bundle\TwigBundle\Tests\TestCase;
|
||||||
use Symfony\Bundle\TwigBundle\TwigBundle;
|
use Symfony\Bundle\TwigBundle\TwigBundle;
|
||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\ErrorRenderer\ErrorRenderer;
|
||||||
use Symfony\Component\HttpKernel\Kernel;
|
use Symfony\Component\HttpKernel\Kernel;
|
||||||
|
|
||||||
class EmptyAppTest extends TestCase
|
class EmptyAppTest extends TestCase
|
||||||
@ -37,12 +39,13 @@ class EmptyAppKernel extends Kernel
|
|||||||
|
|
||||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||||
{
|
{
|
||||||
$loader->load(function ($container) {
|
$loader->load(static function (ContainerBuilder $container) {
|
||||||
$container
|
$container->loadFromExtension('twig', [ // to be removed in 5.0 relying on default
|
||||||
->loadFromExtension('twig', [ // to be removed in 5.0 relying on default
|
'strict_variables' => false,
|
||||||
'strict_variables' => false,
|
'exception_controller' => null,
|
||||||
])
|
]);
|
||||||
;
|
$container->register('error_renderer', ErrorRenderer::class);
|
||||||
|
$container->setParameter('debug.file_link_format', null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ class NoTemplatingEntryKernel extends Kernel
|
|||||||
])
|
])
|
||||||
->loadFromExtension('twig', [
|
->loadFromExtension('twig', [
|
||||||
'strict_variables' => false, // to be removed in 5.0 relying on default
|
'strict_variables' => false, // to be removed in 5.0 relying on default
|
||||||
|
'exception_controller' => null, // to be removed in 5.0 relying on default
|
||||||
'default_path' => __DIR__.'/templates',
|
'default_path' => __DIR__.'/templates',
|
||||||
])
|
])
|
||||||
;
|
;
|
||||||
|
Reference in New Issue
Block a user