From c93231e26bede01135ce942f189679eec24bc8b9 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Sat, 29 Mar 2014 23:54:26 +0100 Subject: [PATCH] improved session error handling fixes #1946 --- extensions/mongodb/Session.php | 11 +++++---- framework/base/ErrorHandler.php | 38 +++++++++++++++++++++++++++++++ framework/mail/BaseMessage.php | 3 ++- framework/web/DbSession.php | 9 ++++---- framework/web/ErrorHandler.php | 26 --------------------- framework/widgets/ActiveField.php | 4 ++-- 6 files changed, 54 insertions(+), 37 deletions(-) diff --git a/extensions/mongodb/Session.php b/extensions/mongodb/Session.php index d7d0954304..02f456a698 100644 --- a/extensions/mongodb/Session.php +++ b/extensions/mongodb/Session.php @@ -8,6 +8,7 @@ namespace yii\mongodb; use Yii; +use yii\base\ErrorHandler; use yii\base\InvalidConfigException; use yii\di\Instance; @@ -49,6 +50,7 @@ class Session extends \yii\web\Session */ public $sessionCollection = 'session'; + /** * Initializes the Session component. * This method will initialize the [[db]] property to make sure it refers to a valid MongoDB connection. @@ -148,10 +150,11 @@ class Session extends \yii\web\Session ['upsert' => true] ); } catch (\Exception $e) { - if (YII_DEBUG) { - echo $e->getMessage(); - } - // it is too late to log an error message here + $exception = ErrorHandler::convertExceptionToString($e); + // its too late to use Yii logging here + error_log($exception); + echo $exception; + return false; } diff --git a/framework/base/ErrorHandler.php b/framework/base/ErrorHandler.php index 82184d15a8..3ba66aab45 100644 --- a/framework/base/ErrorHandler.php +++ b/framework/base/ErrorHandler.php @@ -246,4 +246,42 @@ class ErrorHandler extends Component } } } + + /** + * Converts an exception into a PHP error. + * + * This method can be used to convert exceptions inside of methods like `__toString()` + * to PHP errors because exceptions cannot be thrown inside of them. + * @param \Exception $exception the exception to convert to a PHP error. + */ + public static function convertExceptionToError($exception) + { + trigger_error(static::convertExceptionToString($exception), E_USER_ERROR); + } + + /** + * Converts an exception into a simple string. + * @param \Exception $exception the exception being converted + * @return string the string representation of the exception. + */ + public static function convertExceptionToString($exception) + { + if ($exception instanceof Exception && ($exception instanceof UserException || !YII_DEBUG)) { + $message = "{$exception->getName()}: {$exception->getMessage()}"; + } elseif (YII_DEBUG) { + if ($exception instanceof Exception) { + $message = "Exception ({$exception->getName()})"; + } elseif ($exception instanceof ErrorException) { + $message = "{$exception->getName()}"; + } else { + $message = 'Exception'; + } + $message .= " '" . get_class($exception) . "' with message '{$exception->getMessage()}' \n\nin " + . $exception->getFile() . ':' . $exception->getLine() . "\n\n" + . "Stack trace:\n" . $exception->getTraceAsString(); + } else { + $message = 'Error: ' . $exception->getMessage(); + } + return $message; + } } diff --git a/framework/mail/BaseMessage.php b/framework/mail/BaseMessage.php index 5b1071f99b..3bc2aa602a 100644 --- a/framework/mail/BaseMessage.php +++ b/framework/mail/BaseMessage.php @@ -7,6 +7,7 @@ namespace yii\mail; +use yii\base\ErrorHandler; use yii\base\Object; use Yii; @@ -58,7 +59,7 @@ abstract class BaseMessage extends Object implements MessageInterface try { return $this->toString(); } catch (\Exception $e) { - trigger_error($e->getMessage() . "\n\n" . $e->getTraceAsString()); + ErrorHandler::convertExceptionToError($e); return ''; } } diff --git a/framework/web/DbSession.php b/framework/web/DbSession.php index 6809fd0087..f12960e1fe 100644 --- a/framework/web/DbSession.php +++ b/framework/web/DbSession.php @@ -182,10 +182,11 @@ class DbSession extends Session ->execute(); } } catch (\Exception $e) { - if (YII_DEBUG) { - echo $e->getMessage(); - } - // it is too late to log an error message here + $exception = ErrorHandler::convertExceptionToString($e); + // its too late to use Yii logging here + error_log($exception); + echo $exception; + return false; } diff --git a/framework/web/ErrorHandler.php b/framework/web/ErrorHandler.php index fd8fed3d5f..b6f5188959 100644 --- a/framework/web/ErrorHandler.php +++ b/framework/web/ErrorHandler.php @@ -131,32 +131,6 @@ class ErrorHandler extends \yii\base\ErrorHandler return $array; } - /** - * Converts an exception into a simple string. - * @param \Exception $exception the exception being converted - * @return string the string representation of the exception. - */ - protected function convertExceptionToString($exception) - { - if ($exception instanceof Exception && ($exception instanceof UserException || !YII_DEBUG)) { - $message = "{$exception->getName()}: {$exception->getMessage()}"; - } elseif (YII_DEBUG) { - if ($exception instanceof Exception) { - $message = "Exception ({$exception->getName()})"; - } elseif ($exception instanceof ErrorException) { - $message = "{$exception->getName()}"; - } else { - $message = 'Exception'; - } - $message .= " '" . get_class($exception) . "' with message '{$exception->getMessage()}' \n\nin " - . $exception->getFile() . ':' . $exception->getLine() . "\n\n" - . "Stack trace:\n" . $exception->getTraceAsString(); - } else { - $message = 'Error: ' . $exception->getMessage(); - } - return $message; - } - /** * Converts special characters to HTML entities. * @param string $text to encode. diff --git a/framework/widgets/ActiveField.php b/framework/widgets/ActiveField.php index 56d0df330d..8f2955dd45 100644 --- a/framework/widgets/ActiveField.php +++ b/framework/widgets/ActiveField.php @@ -8,6 +8,7 @@ namespace yii\widgets; use Yii; use yii\base\Component; +use yii\base\ErrorHandler; use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\base\Model; @@ -140,8 +141,7 @@ class ActiveField extends Component try { return $this->render(); } catch (\Exception $e) { - trigger_error($e->getMessage() . "\n\n" . $e->getTraceAsString()); - + ErrorHandler::convertExceptionToError($e); return ''; } }