在每个控制器中处理相同的try catch结构

时间:2013-10-04 12:18:56

标签: php exception symfony exception-handling

我正在使用Symfony2作为我的web项目,我有几个控制器具有完全相同的try catch块

<?php

class MyBaseController extends Controller {
    private $manager = new MyManager();
    // Some generic stuff
}

class MyController1 extends MyBaseController {
    try {
        $manager->one();        
    }
    catch (Exception $e) {
        return $this->someOtherMessage();
    }
}

class MyController2 extends MyBaseController {
    try {
        $manager->two();        
    }
    catch (Exception $e) {
        return $this->someOtherMessage();
    }
}

class MyController3 extends MyBaseController {
    try {
        $manager->three();      
    }
    catch (Exception $e) {
        return $this->someOtherMessage();
    }
}

我怎么写这个以避免这么多重复?

1 个答案:

答案 0 :(得分:1)

如果每个控制器都可以发送特定的异常,则控制器中的每个方法都不需要try / catch块 我认为有两种方法可以解决这个问题。

首先,如果这是一个可以抛出的全局异常,并且您只想渲染另一条消息而不是默认的500错误消息。您可以override给出默认模板,方法是在error500.html.twig文件夹中创建自己的app/Resources

处理它的另一种方法是创建一个与event listener绑定的自定义异常 我会创建自己的异常,例如ManagerException,它将由事件监听器处理。

class ManagerException extends Exception {}

您的经理现在会抛出此异常 注意:只要扩展此基本异常

,您就可以创建所需的任何异常
class RuntimeManagerException extends ManagerException {}

然后您可以声明您的事件监听器

services.yml

services:
    manager_exception.listener:
        class: Acme\FooBundle\Listener\ManagerExceptionListener
        arguments: [ @templating ]
        tags:
            -
                name: kernel.event_listener
                event: kernel.exception
                method: onKernelException

的Acme \ FooBundle \监听\ ManagerExceptionListener

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

class ManagerExceptionListener
{
    protected $twig;

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

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $exception = $event->getException();

        if (!($exception instanceof ManagerException)) {
            return;
        }

        $response = new Response;
        $response->setContent($this->twig->render('errorpage.html.twig'));

        $event->setResponse($response);
    }
}