diff options
Diffstat (limited to 'framework/Web/UI/ActiveControls/TCallbackErrorHandler.php')
-rw-r--r-- | framework/Web/UI/ActiveControls/TCallbackErrorHandler.php | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/framework/Web/UI/ActiveControls/TCallbackErrorHandler.php b/framework/Web/UI/ActiveControls/TCallbackErrorHandler.php new file mode 100644 index 00000000..2acdb7e2 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TCallbackErrorHandler.php @@ -0,0 +1,89 @@ +<?php +/** + * TActivePageAdapter, TCallbackErrorHandler and TInvalidCallbackException class file. + * + * @author Wei Zhuo <weizhuo[at]gamil[dot]com> + * @author Gabor Berczi <gabor.berczi@devworx.hu> (lazyload additions & progressive rendering) + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2014 PradoSoft + * @license http://www.pradosoft.com/license/ + * @package System.Web.UI.ActiveControls + */ + +/** + * TCallbackErrorHandler class. + * + * Captures errors and exceptions and send them back during callback response. + * When the application is in debug mode, the error and exception stack trace + * are shown. A TJavascriptLogger must be present on the client-side to view + * the error stack trace. + * + * @author Wei Zhuo <weizhuo[at]gmail[dot]com> + * @package System.Web.UI.ActiveControls + * @since 3.1 + */ +class TCallbackErrorHandler extends TErrorHandler +{ + /** + * Displays the exceptions to the client-side TJavascriptLogger. + * A HTTP 500 status code is sent and the stack trace is sent as JSON encoded. + * @param Exception exception details. + */ + protected function displayException($exception) + { + if($this->getApplication()->getMode()===TApplication::STATE_DEBUG) + { + $response = $this->getApplication()->getResponse(); + $trace = $this->getExceptionStackTrace($exception); + // avoid error on non-utf8 strings + try { + $trace = TJavaScript::jsonEncode($trace); + } catch (Exception $e) { + // strip everythin not 7bit ascii + $trace = preg_replace('/[^(\x20-\x7F)]*/','', serialize($trace)); + } + + // avoid exception loop if headers have already been sent + try { + $response->setStatusCode(500, 'Internal Server Error'); + } catch (Exception $e) { } + + $content = $response->createHtmlWriter(); + $content->getWriter()->setBoundary(TActivePageAdapter::CALLBACK_ERROR_HEADER); + $content->write($trace); + } + else + { + error_log("Error happened while processing an existing error:\n".$exception->__toString()); + header('HTTP/1.0 500 Internal Server Error', true, 500); + } + $this->getApplication()->getResponse()->flush(); + } + + /** + * @param Exception exception details. + * @return array exception stack trace details. + */ + private function getExceptionStackTrace($exception) + { + $data['code']=$exception->getCode() > 0 ? $exception->getCode() : 500; + $data['file']=$exception->getFile(); + $data['line']=$exception->getLine(); + $data['trace']=$exception->getTrace(); + if($exception instanceof TPhpErrorException) + { + // if PHP exception, we want to show the 2nd stack level context + // because the 1st stack level is of little use (it's in error handler) + if(isset($trace[0]) && isset($trace[0]['file']) && isset($trace[0]['line'])) + { + $data['file']=$trace[0]['file']; + $data['line']=$trace[0]['line']; + } + } + $data['type']=get_class($exception); + $data['message']=$exception->getMessage(); + $data['version']=$_SERVER['SERVER_SOFTWARE'].' '.Prado::getVersion(); + $data['time']=@strftime('%Y-%m-%d %H:%M',time()); + return $data; + } +}
\ No newline at end of file |