Отлов php ошибок

Собственно сабж , как отловить ошибку на mkdir с помощью try catch и исключений в Yii ?

зачем так далеко идти… mkdir возвращает bool, если желаете, можете:


if(false===mkdir($path) && !is_dir($path))

   throw new CException(Yii::t('myapp','Can not create path "{path}"',array('{path}'=>$path)));

не прокатывает , ошибка выбрасывается и перехватывается Yii раньше чем IF(…) , и выбрасывает

Internal Server Error

mkdir(): Error

Дело в том что мне нужно получить сообщение php error : permisiion denied , file exist , и т.п

Как мне это сделать в Yii ?

В PHP существуют специальные функции (is_dir, is_writable, …), в зависимости от возвращаемого значения которых вы можете генерировать соответствующее сообщение.

Тут наткнулся на кусочек и yii в CApplication.php

if(YII_ENABLE_ERROR_HANDLER)

                    set_error_handler(array($this,'handleError'),error_reporting());

тут он перехватывает все ошибки , а как мне получить доступ к ним , посредством обертки блоков try catch или как либо еще ?

если ошибка генерируется самим интерпритатором, то никаким образом вы ее не словите, try-catch здесь не катит, вроде mkdir не генерирует E_ERROR, только E_WARNING, так что можно съесть все собакой false===@mkdir

Если yii перехватывает все ошибки php , и выдает на эти ошибки , в частности на mkdir свои шаблоны сообщений ,

то почему я не могу отловить событие ошибки из yii и выдать свою шибку , например оттранслированную на русский ??

собакой нельзя - у нас стандарт без собак

да и в добавок строчка


if(YII_ENABLE_ERROR_HANDLER)

set_error_handler(array($this,'handleError'),error_reporting());

перехватывает все ошибки и насколько я понимаю warningи тоже , т.к. результат на лицо - yii выдает

сообщение в своем шаблоне.




Internal Server Error

mkdir(): File exists

An internal error occurred while the Web server was processing your request. Please contact the webmaster to report this problem.

Thank you. 

например




function exception_error_handler($errno, $errstr, $errfile, $errline ) {

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);

}

set_error_handler("exception_error_handler");

try {

   mkdir('/somedir');

} catch(ErrorException $ex) {

   echo "Error: " . $ex->getMessage();

}

restore_error_handler()



думаю этого достаточно для понимания что отловить можно все при желании

печально … :)

пустим в ход хаки!? )


$level=error_reporting();

error_reporting($level | ~E_WARNING | ~E_ERROR);


if(!is_dir($path) && false===mkdir($path))

   throw new CException(Yii::t('myapp','Can not create path "{path}"',array('{path}'=>$path)));


error_reporing($level);

(про то, чтобы повесить свой errorHandler, потом по стеку получить того, кто вызвал ошибку, выключить на error_reporing E_ERROR и E_WARNING, запустить “инициатора” повторно, и потом восстановить error_reporting говорить не буду :rolleyes: )

Еще посмотрев в код CApplication…


Yii::app()->onError[]=array($this,'handleError');


...


public function handleError($event){

  $event->handled=true;

  // do smth...

}



может это поможет!? :rolleyes:

Может пригодится…

Мы в текущем проекте столкнулись с приблизительно такой же проблемой: Memcache генерит PHP-ошибки, а не исключения, которые хотя бы через try/catch можно было отловить.

Пришлось изобретать свой хэндлер и "оборачивать" все обращения к мемкешу предвалительно нашим "молчаливым" хэндлером:


/**

 * Наш "молчаливый" хэндлер ошибок, который закрывает от пользователей ошибки

 * соединения с memcached, но при этом пишет в специальный лог информацию об ошибке

 * 

 * @param 

 */

function mcSilenceErrorHandler($errno, $errstr, $errfile, $errline)

{

	QLogger::log('memcache_errors', $errstr . ' at (' . $errfile . ':' . $errline . ')');

	return true;

}

В самом коде используется так, что перед потенциально “опасными” обращениями к мемкешу, мы выставляем свой “молчаливый” хэндлер, а потом возвращаем старый - Yii’шный - хэндлер.




//...

	/**

	 * Deletes all values from cache.

	 * Be careful of performing this operation if the cache is shared by multiple applications.

	 * 

	 * @return boolean if no error happens during flush cache

	 */

	public function flush()

	{

		$result = false;

		

		$old_handler = set_error_handler('mcSilenceErrorHandler');

		$result = $this->_cache->flush();

		set_error_handler($old_handler);

		

		return $result;

	}

//...