PHP / Symfony – 为什么使用Twig呈现的控制器的异常仅未在生产模式中捕获?

我有2个控制器动作,一个通过渲染(控制器(…))函数在另一个的树枝模板中渲染.如果我在子动作中抛出一个异常,它只会在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!");
    }
}

child.html.twig

Child

parent.html.twig

Parent
<br>
{{ render(controller("WebBundle:Pages:child")) }}

结果:

enter image description here

解决方法

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

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

// app/config/config.yml
twig:
    # ...
    debug: true # default: %kernel.debug%

或者,配置异常监听器:

服务声明:

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

类:

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));
    }
}

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

// 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 %}

编辑

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

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

希望这可以帮助.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...