1. * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error. * * ### Implementing application specific exception rendering * * You can implement application specific exception handling in one of a few ways: * * - Create a AppController::appError(); * - Create a subclass of YAExceptionRenderer and configure it to be the `Exception.renderer` * * #### Using AppController::appError(); * * This controller method is called instead of the default exception handling. It receives the * thrown exception as its only argument. You should implement your error handling in that method. * * #### Using a subclass of YAExceptionRenderer * * Using a subclass of YAExceptionRenderer gives you full control over how Exceptions are rendered, you * can configure your class in your core.php, with `Configure::write('Exception.renderer', 'MyClass');` * You should place any custom exception renderers in `app/Lib/Error`. * * @package NetCommons\NetCommons\Error */ class NetCommonsExceptionRenderer extends ExceptionRenderer { /** * Convenience method to display a 400 series page. * * @param Exception $error Exception * @return void */ public function error400($error) { $message = $error->getMessage(); $this->controller->response->statusCode($error->getCode()); if ($message === 'The request has been black-holed') { $redirect = $this->controller->request->referer(true); } elseif ($message === 'Bad ip address') { $this->controller->Session->destroy(); $redirect = null; } elseif ($message === 'Under maintenance') { $redirect = '/net_commons/site_close/index'; $this->controller->Session->destroy(); } elseif ($message === 'Permission denied' || $error->getCode() === 403) { list($redirect, $redirectUrl) = $this->__get403And404Redirect(); if (! $this->controller->request->is('ajax')) { $this->controller->Auth->redirectUrl($redirectUrl); } } else { $redirect = '/'; $this->controller->Session->destroy(); } if (isset($redirect)) { $redirect = Router::url($redirect); } $results = array( 'message' => $this->__get400Message($error), 'redirect' => $redirect, 'interval' => '3' ); $this->__setError('NetCommons.error400', $error, $results); } /** * エラーメッセージ取得 * * @param Exception $error Exception * @return string $message */ private function __get400Message($error) { $message = $error->getMessage(); if (! Configure::read('debug') && $error instanceof CakeException) { $message = 'Not Found'; } if ($message === 'Under maintenance') { $message = __d( 'net_commons', 'Under maintenance. Nobody is allowed to login except for administrators.' ); } elseif ($message === 'Permission denied') { if ($this->controller->Auth->user()) { $message = __d('net_commons', 'Permission denied. Bad account.'); } else { $message = __d('net_commons', 'Permission denied. You must be logged.'); } } else { $message = __d('net_commons', $message); } return h($message); } /** * リダイレクトURLを取得する。 * * @return array array($redirect, $redirectUrl) */ private function __get403And404Redirect() { if ($this->controller->Auth->user()) { $referer = Router::parse($this->controller->request->referer(true)); $here = Router::parse($this->controller->request->here(false)); if ($referer['action'] === 'login' || $here['action'] === 'login') { $SiteSetting = ClassRegistry::init('SiteManager.SiteSetting'); $redirect = $SiteSetting->getDefaultStartPage(); $redirectUrl = $redirect; } else { $redirect = '/'; $redirectUrl = '/'; } } else { $redirect = '/auth/login'; $this->controller->Session->destroy(); App::uses('Current', 'NetCommons.Utility'); if (in_array($this->controller->params['action'], ['index', 'view'], true)) { $redirectUrl = $this->controller->request->here(false); } elseif (Current::read('Page.permalink')) { $redirectUrl = '/' . Current::read('Page.permalink'); } else { $redirectUrl = '/'; } } return array($redirect, $redirectUrl); } /** * Convenience method to display a 500 page. * * @param Exception $error Exception * @return void */ public function error500($error) { $message = $error->getMessage(); if (! Configure::read('debug')) { $message = __d('net_commons', 'An Internal Error Has Occurred.'); } if ($error->getCode() > 500 && $error->getCode() < 506) { $code = $error->getCode(); } else { $code = 500; } $this->controller->response->statusCode($code); $results = array( 'message' => h($message), ); $this->__setError('NetCommons.error500', $error, $results); } /** * エラーをコントローラにセット * * @param string $template viewテンプレート * @param Exception $error Exception * @param array $results viewにセットする配列 * @return void */ private function __setError($template, $error, $results) { $url = $this->controller->request->here(); $name = preg_replace('/Exception$/', '', get_class($error)); if ($name === '') { $name = get_class($error); } $results = Hash::merge(array( 'code' => $error->getCode(), 'name' => Inflector::humanize(Inflector::underscore($name)), 'url' => h($url), ), $results); if ($this->controller->request->is('ajax')) { $this->controller->viewClass = 'Json'; $this->controller->layout = false; if (Configure::read('debug')) { $results['error'] = ['trace' => explode("\n", $error->getTraceAsString())]; } $this->controller->set(compact('results')); } else { $this->controller->layout = 'NetCommons.error'; $results['error'] = $error; $this->controller->set($results); } $this->controller->set('_serialize', 'results'); $this->_outputMessage($template); } }