/**
  * Handle errors and exceptions
  *
  * If the 'noErrorHandler' front Controller flag has been set,
  * returns early.
  *
  * @param  Zend_Controller_Request_Abstract $request
  * @return void
  */
 protected function _handleError(RThink_Controller_Request $request, RThink_Controller_Response $response)
 {
     $frontController = RThink_Controller_Front::getInstance();
     if ($frontController->getParam('noErrorHandler')) {
         return;
     }
     if ($this->_isInsideErrorHandlerLoop) {
         $exceptions = $response->getException();
         if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) {
             // Exception thrown by error handler; tell the front Controller to throw it
             $frontController->throwExceptions(true);
             throw array_pop($exceptions);
         }
     }
     // check for an exception AND allow the error handler Controller the option to forward
     if ($response->isException() && !$this->_isInsideErrorHandlerLoop) {
         $this->_isInsideErrorHandlerLoop = true;
         // Get exception information
         $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
         $exceptions = $response->getException();
         $exception = $exceptions[0];
         $error->exception = $exception;
         $exceptionType = get_class($exception);
         $error->exception = $exception;
         switch ($exceptionType) {
             case 'RThink_Controller_Router_Exception':
                 if (404 == $exception->getCode()) {
                     $error->type = self::EXCEPTION_NO_ROUTE;
                 } else {
                     $error->type = self::EXCEPTION_OTHER;
                 }
                 break;
             case 'RThink_Controller_Dispatcher_Exception':
                 $error->type = self::EXCEPTION_NO_CONTROLLER;
                 break;
             case 'RThink_Controller_Action_Exception':
                 if (404 == $exception->getCode()) {
                     $error->type = self::EXCEPTION_NO_ACTION;
                 } else {
                     $error->type = self::EXCEPTION_OTHER;
                 }
                 break;
             default:
                 $error->type = self::EXCEPTION_OTHER;
                 break;
         }
         // get a count of the number of exceptions encountered
         $this->_exceptionCountAtFirstEncounter = count($exceptions);
         // Keep a copy of the original Request
         $error->request = clone $request;
         // Forward to the error handler
         $request->setParam('error_handler', $error)->setModuleName($this->getErrorHandlerModule())->setControllerName($this->getErrorHandlerController())->setActionName($this->getErrorHandlerAction())->setDispatched(false);
     }
 }
Example #2
0
 /**
  * 派遣请求到 Controller/action.
  *  处理线索 dispatch(RThink_Controller_Front) ->dispatch(RThink_Controller_DispatcherStandard) -> dispatch(RThink_Controller_Action)
  * 最终还是交由动作控制器自己分发
  *
  * @return void RThink_Controller_Response Response object if returnResponse() is true
  */
 public function dispatch()
 {
     $_plugins = array();
     if ($this->getParam('plugins')) {
         //            if (!$this->getParam('plugin_path')) {
         //                throw new RThink_Exception("插件注册失败!入口文件没有指定plugin_path!");
         //            }
         foreach ($this->getParam('plugins') as $plugin) {
             //                include $this->getParam('plugin_path') . '/' . $plugin . '.php';
             include APP_PATH . '/app/plugins/' . $plugin . '.php';
             $_plugins[] = new $plugin();
         }
     }
     if (!$this->getParam('noErrorHandler')) {
         include 'RThink/Controller/Plugin/ErrorHandler.php';
         $_plugins[] = new RThink_Controller_Plugin_ErrorHandler();
     }
     $this->_plugins->registerPlugin($_plugins);
     /**
      * 获取请求对象
      */
     if (null === $this->_request) {
         $this->getRequest();
     }
     /**
      * 获取响应对象
      */
     if (null === $this->_response) {
         $this->getResponse();
     }
     /**
      * Initialize Router
      */
     $router = $this->getRouter();
     /**
      * 初始化派遣器
      */
     $dispatcher = $this->getDispatcher();
     $dispatcher->setParams($this->getParams())->setResponse($this->_response);
     // 开始派遣
     try {
         /**
          * Notify plugins of Router startup
          */
         $this->_plugins->routeStartup($this->_request, $this->_response);
         try {
             $router->route($this->_request);
         } catch (Exception $e) {
             if ($this->throwExceptions()) {
                 throw $e;
             }
             $this->_response->setException($e);
         }
         /**
          * Notify plugins of Router completion
          */
         $this->_plugins->routeShutdown($this->_request, $this->_response);
         /**
          * Notify plugins of dispatch loop startup
          */
         $this->_plugins->dispatchLoopStartup($this->_request, $this->_response);
         /**
          * 尝试派遣controller/action.如果 $this->_request表明需要被派遣,
          * 移动到request的下一个action
          */
         do {
             $this->_request->setDispatched(true);
             /**
              * Notify plugins of dispatch startup
              */
             $this->_plugins->preDispatch($this->_request, $this->_response);
             /**
              * 如果 preDispatch() 重置了请求的action则跳过
              */
             if (false == $this->_request->isDispatched()) {
                 continue;
             }
             /**
              * 派遣请求
              */
             try {
                 $dispatcher->dispatch($this->_request, $this->_response);
             } catch (Exception $e) {
                 if ($this->throwExceptions()) {
                     throw $e;
                 }
                 $this->_response->setException($e);
             }
             /**
              * Notify plugins of dispatch completion
              */
             $this->_plugins->postDispatch($this->_request, $this->_response);
         } while (!$this->_request->isDispatched());
     } catch (Exception $e) {
         if ($this->throwExceptions()) {
             throw $e;
         }
         $this->_response->setException($e);
     }
     /**
      * Notify plugins of dispatch loop completion
      */
     try {
         $this->_plugins->dispatchLoopShutdown($this->_response);
     } catch (Exception $e) {
         if ($this->throwExceptions()) {
             throw $e;
         }
         $this->_response->setException($e);
     }
     if ($this->_request->getParam('db_debug')) {
         RThink_Debug::dbDebug();
     }
     if ($this->returnResponse()) {
         return $this->_response;
     }
     $this->_response->sendResponse();
 }