обработка исключений и ошибок

profan

Новичок
обработка исключений и ошибок

Нужно чтоб ошибки и необработанные исключения обрабатывала спец функция (err2exc), а если есть блок try - catch исключение должно обрабатываться в нем
Например есть такой код:

PHP:
class myException extends exception {
    public function __construct($errno=null, $errstr=null, $errfile=null, $errline=null) {
        parent::__construct();
        $this->code = $errno;
        $this->message = $errstr;
        $this->file = $errfile;
        $this->line = $errline;
        
    }
}

function err2exc($errno, $errstr, $errfile, $errline) {   
    $PHP_ERROR = (func_num_args() === 5);
    if ($PHP_ERROR AND (error_reporting() & $errno) === 0)
        return;
    echo $errno;
    exit;
}

set_error_handler('err2exc', E_ALL & ~E_NOTICE & ~E_USER_NOTICE );   
set_exception_handler('err2exc');

class DDR {
	public function query($sql)
	{       
                if (!$res = pg_query($this->conn, $sql))
                       throw new myException('database.error', pg_last_error().' - '.$sql);
        	return $res;	                      
	}	
}

$dbr = new DDR();
try {
      $result = $dbr->query($query);         
} 
catch (exception $e) {
      echo $e->getMessage();
}
если будет неправильный запрос то в этом случае исключение не попадает в catch так как pg_query() в DDR:query() возвращает ошибку и управление передается в err2exc(). Выходом в этом случае будет подавить ошибку @pg_query() и в err2exc() сделать проверку if ($PHP_ERROR AND (error_reporting() & $errno) === 0) return; тогда error_reporting() в err2exc() равно 0 и при проверки происходит выход из err2exc() и управление переходит в catch. А если блока try - catch нет, то управление возвращается обратно в err2exc() и тогда error_reporting() уже равно коду ошибки и исключение обрабатывает err2exc().
Все описанное это результат экспериментов, но решение выглядит как грязный хак.
Поэтому хотелось бы совета, как это реализовать правильно.
И еще непонятно почему несмотря на то что есть конструкция try - catch, управление передается не туда, а в exception hendler. Хотя в документации написано, что должно быть наоборот.
 

profan

Новичок
zerkms
тоесть вы имеете ввиду что у меня абстрактное исключение и поэтому оно игнорируется и поэтому управление передается в exeption hendler, а не в catch?
И если это будет тип Exception то тогда такое исключение тоже не должно попадать в catch?

Ну я в PHP знаю только один системный класс от которого наследуются остальные исключения (Exception), а не как написано в статье (про Java): описываемые в прототипе метода, RuntimeException и Error.
Поэтому неочень понимаю что значит правильный тип исключения. Какая разница интерпритатору, что ошибку соединения с БД будет обрабатывать class::Exception или class:: Database_Exception extends Exception в котором что-то добавлено.
Вот буду признателен за разъяснение этого момента...
 

itprog

Cruftsman
profan
Красивее будет конвертнуть все ошибки в исключения. После можно просто перебросить:
PHP:
try {
    $res = pg_query($this->conn, $sql);
} catch (phpErrorException $e) {
    throw new databaseQueryException($e);
}
 

zerkms

TDD infected
Команда форума
profan
у тебя управление передаётся в еррор_хандлер потому, что оно вызывается раньше, до того как кидается исключение.
как мне кажется, куда проще конвертировать ВСЕ ОШИБКИ в исключения, а затем их отлавливать примерно по такой схеме: try { // весь проект } catch (не пойманные + стандартные ошибки пхп) {}
 

profan

Новичок
itprog
>конвертнуть все ошибки в исключения
имееся ввиду это:

PHP:
class ErrorException    extends   Exception  

function exception_error_handler($errno, $errstr, $errfile, $errline ){
      throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
?
 

profan

Новичок
zerkms
>у тебя управление передаётся в еррор_хандлер потому, что оно вызывается раньше, до того как кидается исключение.

так это и непонятно. почему так. ведь должно вызываться только тогда когда нет блоков try - catch по всему "стеку" вызовов. Так ведь?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Есть предположение, что ты ждешь от PHP такой же принцип работы с исключениями и ошибками, как ты прочитал в книге про Java.
PHP - не Java, тут работает иначе. Исключение и Ошибка - разные понятия, они почти не пересекаются.
При неправильном запросе исключение не выкидывается, выкидывается ошибка. Образно говоря, ошибка имеет больший приоритет.

Идея itprog в том, чтобы отлавливать ошибки и бросать из хендлера исключения. На мой личный взгляд, это решение имеет недостаток - необходимость всегда вручную прописывать обработку исключений, даже там, где удобней просто ошибки обрабатывать.
 
Сверху