Commit a4b6fb26 by Carsten Brandt

handle Exceptions in application init()

parent 89f6a001
...@@ -179,15 +179,8 @@ abstract class Application extends Module ...@@ -179,15 +179,8 @@ abstract class Application extends Module
$this->state = self::STATE_BEGIN; $this->state = self::STATE_BEGIN;
// TODO how to deal with exceptions thrown in preInit() $this->registerErrorHandler($config);
$this->preInit($config); $this->preInit($config);
if (YII_ENABLE_ERROR_HANDLER) {
if (isset($config['components']['errorHandler'])) {
$this->set('errorHandler', $config['components']['errorHandler']);
unset($config['components']['errorHandler']);
}
$this->getErrorHandler()->register();
}
Component::__construct($config); Component::__construct($config);
} }
...@@ -203,13 +196,13 @@ abstract class Application extends Module ...@@ -203,13 +196,13 @@ abstract class Application extends Module
public function preInit(&$config) public function preInit(&$config)
{ {
if (!isset($config['id'])) { if (!isset($config['id'])) {
throw new InvalidConfigException('The "id" configuration is required.'); throw new InvalidConfigException('The "id" configuration for the Application is required.');
} }
if (isset($config['basePath'])) { if (isset($config['basePath'])) {
$this->setBasePath($config['basePath']); $this->setBasePath($config['basePath']);
unset($config['basePath']); unset($config['basePath']);
} else { } else {
throw new InvalidConfigException('The "basePath" configuration is required.'); throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
} }
if (isset($config['vendorPath'])) { if (isset($config['vendorPath'])) {
...@@ -292,6 +285,22 @@ abstract class Application extends Module ...@@ -292,6 +285,22 @@ abstract class Application extends Module
} }
/** /**
* Registers the errorHandler component as a PHP error handler.
*/
protected function registerErrorHandler(&$config)
{
if (YII_ENABLE_ERROR_HANDLER) {
if (!isset($config['components']['errorHandler']['class'])) {
echo "Error: no errorHandler component is configured.\n";
exit(1);
}
$this->set('errorHandler', $config['components']['errorHandler']);
unset($config['components']['errorHandler']);
$this->getErrorHandler()->register();
}
}
/**
* Returns an ID that uniquely identifies this module among all modules within the current application. * Returns an ID that uniquely identifies this module among all modules within the current application.
* Since this is an application instance, it will always return an empty string. * Since this is an application instance, it will always return an empty string.
* @return string the unique ID of the module. * @return string the unique ID of the module.
......
...@@ -95,7 +95,7 @@ abstract class ErrorHandler extends Component ...@@ -95,7 +95,7 @@ abstract class ErrorHandler extends Component
if (PHP_SAPI === 'cli') { if (PHP_SAPI === 'cli') {
echo $msg . "\n"; echo $msg . "\n";
} else { } else {
echo '<pre>' . htmlspecialchars($msg, ENT_QUOTES, $this->charset) . '</pre>'; echo '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>';
} }
} }
$msg .= "\n\$_SERVER = " . var_export($_SERVER, true); $msg .= "\n\$_SERVER = " . var_export($_SERVER, true);
......
...@@ -189,9 +189,19 @@ class Application extends \yii\base\Application ...@@ -189,9 +189,19 @@ class Application extends \yii\base\Application
public function coreComponents() public function coreComponents()
{ {
return array_merge(parent::coreComponents(), [ return array_merge(parent::coreComponents(), [
'errorHandler' => ['class' => 'yii\console\ErrorHandler'],
'request' => ['class' => 'yii\console\Request'], 'request' => ['class' => 'yii\console\Request'],
'response' => ['class' => 'yii\console\Response'], 'response' => ['class' => 'yii\console\Response'],
]); ]);
} }
/**
* Registers the errorHandler component as a PHP error handler.
*/
protected function registerErrorHandler(&$config)
{
if (!isset($config['components']['errorHandler']['class'])) {
$config['components']['errorHandler']['class'] = 'yii\\console\\ErrorHandler';
}
parent::registerErrorHandler($config);
}
} }
...@@ -147,11 +147,21 @@ class Application extends \yii\base\Application ...@@ -147,11 +147,21 @@ class Application extends \yii\base\Application
public function coreComponents() public function coreComponents()
{ {
return array_merge(parent::coreComponents(), [ return array_merge(parent::coreComponents(), [
'errorHandler' => ['class' => 'yii\web\ErrorHandler'],
'request' => ['class' => 'yii\web\Request'], 'request' => ['class' => 'yii\web\Request'],
'response' => ['class' => 'yii\web\Response'], 'response' => ['class' => 'yii\web\Response'],
'session' => ['class' => 'yii\web\Session'], 'session' => ['class' => 'yii\web\Session'],
'user' => ['class' => 'yii\web\User'], 'user' => ['class' => 'yii\web\User'],
]); ]);
} }
/**
* Registers the errorHandler component as a PHP error handler.
*/
protected function registerErrorHandler(&$config)
{
if (!isset($config['components']['errorHandler']['class'])) {
$config['components']['errorHandler']['class'] = 'yii\\web\\ErrorHandler';
}
parent::registerErrorHandler($config);
}
} }
...@@ -66,7 +66,11 @@ class ErrorHandler extends \yii\base\ErrorHandler ...@@ -66,7 +66,11 @@ class ErrorHandler extends \yii\base\ErrorHandler
*/ */
protected function renderException($exception) protected function renderException($exception)
{ {
if (Yii::$app->has('response')) {
$response = Yii::$app->getResponse(); $response = Yii::$app->getResponse();
} else {
$response = new Response();
}
$useErrorView = $response->format === \yii\web\Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException); $useErrorView = $response->format === \yii\web\Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException);
...@@ -80,7 +84,7 @@ class ErrorHandler extends \yii\base\ErrorHandler ...@@ -80,7 +84,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
} elseif ($response->format === \yii\web\Response::FORMAT_HTML) { } elseif ($response->format === \yii\web\Response::FORMAT_HTML) {
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' || YII_ENV_TEST) { if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' || YII_ENV_TEST) {
// AJAX request // AJAX request
$response->data = '<pre>' . htmlspecialchars($this->convertExceptionToString($exception), ENT_QUOTES, Yii::$app->charset) . '</pre>'; $response->data = '<pre>' . $this->htmlEncode($this->convertExceptionToString($exception)) . '</pre>';
} else { } else {
// if there is an error during error rendering it's useful to // if there is an error during error rendering it's useful to
// display PHP error in debug mode instead of a blank screen // display PHP error in debug mode instead of a blank screen
...@@ -175,7 +179,7 @@ class ErrorHandler extends \yii\base\ErrorHandler ...@@ -175,7 +179,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
public function renderFile($_file_, $_params_) public function renderFile($_file_, $_params_)
{ {
$_params_['handler'] = $this; $_params_['handler'] = $this;
if ($this->exception instanceof ErrorException) { if ($this->exception instanceof ErrorException || !Yii::$app->has('view')) {
ob_start(); ob_start();
ob_implicit_flush(false); ob_implicit_flush(false);
extract($_params_, EXTR_OVERWRITE); extract($_params_, EXTR_OVERWRITE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment