PHP / Symfony-为什么用Twig渲染的控制器异常不是仅在生产模式下捕获?

Mik*_*ike 5 php exception try-catch symfony

我有2个控制器动作,一个通过render(controller(...))函数在另一个的树枝模板中呈现。如果我在子操作中抛出异常,则仅在DEV模式下捕获该异常,而在PRODuction中则未捕获该异常,为什么以及如何解决该问题的任何想法?

DefaultController.php

/**
 * @Route("/test/child", name="test_child")
*/
public function childAction(Request $request)
{
    throw new \Exception($request->getRequestUri());

    return $this->render("child.html.twig");
}

/**
 * @Route("/test/parent", name="test_parent")
 */
public function parentAction(Request $request)
{
    try {
        return $this->render("parent.html.twig");
    } catch(\Exception $e)
    {
        die("got it!");
    }
}
Run Code Online (Sandbox Code Playgroud)

child.html.twig

Child
Run Code Online (Sandbox Code Playgroud)

parent.html.twig

Parent
<br>
{{ render(controller("WebBundle:Pages:child")) }}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

cha*_*asr 4

在 Symfony2 项目中,Twig 在生产模式下默认捕获异常。

您可以对其进行配置,以便像开发模式一样抛出所有异常:

// app/config/config.yml
twig:
    # ...
    debug: true # default: %kernel.debug%
Run Code Online (Sandbox Code Playgroud)

或者,配置异常监听器:

服务声明:

// app/config/services.yml
app.exception_listener:
    class: Acme\CoreBundle\Listener\ExceptionListener
    arguments: [ "@templating" ]
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
Run Code Online (Sandbox Code Playgroud)

班级:

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Templating\EngineInterface;

class ExceptionListener
{
    private $templateEngine;

    public function __construct(EngineInterface $templateEngine)
    {
        $this->templateEngine = $templateEngine;
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $response = $this->templateEngine->render(
            'TwigBundle:Exception:error500.html.twig',
            array('status_text' => $event->getException()->getMessage())
        );
        $event->setResponse(new Response($response));
    }
}
Run Code Online (Sandbox Code Playgroud)

异常消息跟踪/消息显示模板:

// app/Resources/TwigBundle/views/Exception/error500.html.twig
{% extends '::base.html.twig' %}

{% block body %}
    <div class='error'>
        <div class="message">
            <h2>Application Error</h2>
            <p>Oops! {{ status_text }}</p>
        </div>
    </div>
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

编辑

要仅捕获特定异常,请在侦听器的开头添加以下内容:

// Listen only on the expected exception
if (!$event->getException() instanceof RedirectException) {
    return;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。