Zend Framework 2 - 捕获和记录异常(包括工厂内)的最佳方法

时间:2014-12-11 14:46:59

标签: php error-handling zend-framework2

下面的Zend Framework 2代码创建了一个Elastic Search客户端。但是,如果由于服务不可用而无法连接到弹性搜索,则会引发异常。

class ElasticClientFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return \Elasticsearch\Client
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        return new Client(
            $serviceLocator->get('Config')['elastic']['cluster']
        );
    }
}

我的理解是,要在Zend中创建默认错误处理程序,我应该使用以下内容。

$sharedManager = $event->getApplication()->getEventManager()->getSharedManager();
        $sm = $event->getApplication()->getServiceManager();
        $sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
            function($event) use ($sm) {
            if ($event->getParam('exception')){
                $sm->get('Logger')->crit($event->getParam('exception'));
            }
        });

但是,此代码仅捕获控制器中或调度过程中的异常。有没有办法捕获使用工厂创建服务时抛出的异常。例如,如果数据库出现故障或应用程序尝试连接的任何服务,可能会发生这种情况。我似乎无法找到正确的方法来捕获工厂中抛出的异常,并让它们由上面的全局错误处理程序处理。

为了解决这个问题,我现在已经在记录器上注册了一个异常处理程序,它将记录工厂中抛出的异常,但这感觉不正确。

Logger::registerExceptionHandler($logger);

1 个答案:

答案 0 :(得分:2)

最后,我创建了一个单独的Zend Framework 2模块,并在onBootstrap方法中执行了以下操作

 public function onBootstrap(MvcEvent $event)
    {
        $eventManager        = $event->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);

        $logger = $event->getApplication()->getServiceManager()->get('Logger');

在发送期间捕获错误的例外

  $sharedManager = $event->getApplication()->getEventManager()->getSharedManager();
    $sm = $event->getApplication()->getServiceManager();
    $sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
        function($event) use ($sm) {
        if ($event->getParam('exception')){
            $sm->get('Logger')->crit($event->getParam('exception'));
        }
    });

捕获未被捕获的应用程序代码中的异常。例如,如果数据库服务器出现故障。

set_exception_handler(function($exception) use ($sm, $event) {
            //ensure that the application log, logs a 500 error
            $event->getResponse()->setStatusCode(500);
            $extractor->setResponse($event->getResponse());
            http_response_code(500);
            $sm->get('Logger')->crit($exception);
    });

在响应上设置400或500错误消息时记录的全局捕获。这主要用于记录目的。

$eventManager->attach(MvcEvent::EVENT_FINISH,
        function ($e) use ($logger) {
            $statusCode = $e->getResponse()->getStatusCode();
            $sm = $e->getApplication()->getServiceManager();
            if($statusCode >= 500) {
                $e->getResponse()->setStatusCode($statusCode);
                $sm->get('Logger')->crit($e->getResponse());
            }
            if($statusCode >= 400 && $statusCode < 500) {
                $e->getResponse()->setStatusCode($statusCode);
                $sm->get('Logger')->err($e->getResponse());
            }

        }
    );