如何将Bootstrap中生成的错误转发给ErrorController?

时间:2011-04-09 18:46:53

标签: php zend-framework error-handling

我正在使用Zend Tool为我生成的默认ErrorController。我的index.php文件的第一件事就是注册一个错误处理程序,将错误和警告转换为异常:

function handleError($errno, $errstr, $errfile, $errline, array $errcontext) {
    // error was suppressed with the @-operator
    if (0 === error_reporting()) {
        return false;
    }

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler('handleError');

我也在index.php中设置了这个:

$front = Zend_Controller_Front::getInstance();
$front->throwExceptions(false);

问题是它不处理来自Bootstrap文件的异常。异常触发,但ErrorController不会启动它。页面的执行只是暂停,没有视图呈现。

如何通过错误控制器路由每个异常和警告(当然,语法和致命错误除外)?

3 个答案:

答案 0 :(得分:2)

但是如果连接到数据库JIT(Just In Time),应该没有问题。实际上,您可以使用Front Controller插件在引导程序之后移动数据库连接。如果您不需要设置其他内容(例如路由,某些预调度转换等),则数据库连接设置可以在_dispatchLoopStartup()

//in bootstrap
$front->registerPlugin(new Awesome_Db_Plugin($zendConfigWithDbOptions));
// in plugin (options injected via constructor to private member
public function dispatchLoopStartup() {
    $db = Zend_Db::factory($this->_options);
    Zend_Registry::set('db', $db);
}

这样,数据库连接期间抛出的每个异常都将在$front->dispatch();

之后触发

答案 1 :(得分:2)

这是来自我的index.php,可能会有用:

//bootstrap, and run application
try {
    require_once 'Zend/Application.php';
    //create application and configure it.
    $application = new Zend_Application(
        getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production',
        array('config' => array(APPLICATION_PATH . DS . 'configs' . DS . 'application.ini'))
    );
    //run application
    $application->bootstrap()->run();
} catch (Exception $e) {
    //fallback for uncatched exceptions
    ob_clean();
    //ensure error will be logged and firephp backend, if enabled, will send log messages
    if(is_object($application)
        && $application->bootstrap('log')
        && Zend_Registry::isRegistered('Zend_Log')
    ) {
        Zend_Registry::get('Zend_Log')
            ->log($e,Zend_Log::CRIT);
    }
    $wildfire = Zend_Wildfire_Channel_HttpHeaders::getInstance();
    if(!($response = Zend_Controller_Front::getInstance()->getResponse())) {
        $response = new Zend_Controller_Response_Http();
        $wildfire->setRequest(new Zend_Controller_Request_Http());
        $wildfire->setResponse($response);
    }
    if($response->canSendHeaders()) {
        $response->clearHeaders();
        $response->setHttpResponseCode(500);
        $wildfire->flush();
        $response->sendResponse();
    }
    //put static html for error page here
    echo 'Startup error occured. Try again later';
}

注意Zend_Registry::isRegistered('Zend_Log')在扩展应用程序资源中使用注册表注册的Zend_Log实例

答案 2 :(得分:1)

如果Bootstrap中发生异常,则无法将其传递给ErrorController,因为您的应用程序尚未设置,因此它还不知道ErrorController

你必须使用其他东西来处理它。

拥有一个极有可能在Bootstrap中抛出未被捕获的异常的应用程序肯定不是一件好事。您应该捕获Bootstrap中发生的异常并相应地处理它们。