【问题标题】:Zend Framework 2 - Best way to of catching and logging exceptions including within factoriesZend Framework 2 - 捕捉和记录异常的最佳方式,包括在工厂内
【发布时间】:2014-12-11 14:46:58
【问题描述】:

下面的 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);

【问题讨论】:

  • 我认为最好的方法是在工厂中尝试/捕获异常,这样您可以选择返回 false 或空客户端...此外,服务在工厂建设期间可用(您可以访问 $serviceLocator),因此您可以注册一个 Logger 并使用它来记录您的错误,而不会干扰 MVC 进程堆栈。我只是认为在工厂过程中处理工厂错误很顺利。最终,使用生成的实例时的错误和异常将在之后处理(如失败的请求......等),例如在控制器中。

标签: php error-handling zend-framework2


【解决方案1】:

最后我创建了一个单独的 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());
            }

        }
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多