Отладочный слой. Вывод/перехват ошибок.

white phoenix

Новичок
Отладочный слой. Вывод/перехват ошибок.

Есть lib выполненая в виде класса, его задача - обмен данными с удаленным сервером втечение долгого промежутка времени, естественно могут возникать ситуации в которых нужно вывести сообщение об ошибке/предупреждение и т.п. Глубина вложенности вызовов порой доходит до 20, и для отладки требуется backtrace. Нужно сделать возможность перехвата ошибок, т.е. чтобы скрипт который использует данную библеотеку мог максимально удобно получить оповещение о произошедшей ошибке (например об отсоеденении от сервера), и сделать соответствующие действия, например вывести сообщение в GTK. Вот так сейчас передается ошибка (пример):
PHP:
$this->dbg->_send('E_WARNING','connection failed ('.socket_last_error().' - '.socket_strerror(socket_last_error()).')');
Подскажите, как лучше всего реализовать перехват? Подчеркиваю что кода мне не нужно, только намекните на оптимальный путь. Моё решение (возможно кривое):
Из каждой ошибки которая может быть перехвачена сделать сокращеный текст (оформить как константу). Для вышеприведенной ошибки это будет выглядело бы вот как:
PHP:
$this->dbg->_send('E_WARNING','CONN_FAILED',array(socket_last_error(),socket_strerror(socket_last_error()));
Далее метод _send смотрит нет ли сведений об этой ошибке в массиве перенаправления, который был бы вида
PHP:
array(
'CONN_FAILED' => array($callback,$hide_error),
//...
Где $callback - ссылка на callback-функцию, $hide_error - логическое значение "отключить ли показ сообщения в STDOUT". Если же в массиве перенаправления ошибка не значится то: если уровень показа ошибок больше или равен уровню ошибки, то показываем в STDOUT следущим образом: наверно Вы обратили внимание на третий аргумент метода _send который отвечает за переменные в сообщении об ошибке, можно сделать еще один массив, где ключи - строки типа 'CONN_FAILED', а значения например 'connection failed (%s - %s)'. Как Вы наверно уже догадались будет sprintf($errstr,$errvars).
При этом хотелось сохранять backtrace в читабельном виде (думаю что var_dump) если библеотека работает в отладочном режиме.
Поверьте, что этот гемор того стоит, куда больший гемор отлаживать без него.
Спасибо всем!
 

Profic

just Profic (PHP5 BetaTeam)
Подскажите, как лучше всего реализовать перехват?
Поставить xdebug. Он при любых сообщениях php об ошибках выдает backtrace в стандартный вывод в читабельном виде. А т.к. большинство встроенных ф-ций чего-нить да генерируют при ошибках, то понять где искать проблемы обычно труда не составляет. Далее уже в этом месте начинаем втыкать var_dump()-ы, благо xdebug эту ф-цию заменяет на свою, которая выдает результат уже в html.
 

white phoenix

Новичок
Profic
Спасибо, но мне бы хотелось сделать это без нестандартных pecl-модулей.

Мой вариант не слишком извращенный? Как обычно решают такие задачи?
 

Profic

just Profic (PHP5 BetaTeam)
Ну на devel машине можно позволить себе нестандартный модуль :).
Способ по своей идее по мооему мнению извращенный, но не слишком :). Как говорилось выше почти все встроенные ф-ции php генерируют ошибки, и никто не машает их перехватывать и выдавать в нужном виде. Если же нужно красивые сообщения пользователю, тут имхо, любой вариант, удобный для программита имет право на жизнь.
 

white phoenix

Новичок
Profic
Ошибки функций PHP (типа trigger_error) меня не интересуют, я говорил про вывод ошибок в собственных функциях.

-~{}~ 23.12.05 22:02:

> имхо, любой вариант, удобный для программита имет право на жизнь.
Тоже так думаю, но мне казалось есть более красивый способ.
 

Setor

Новичок
Ошибки функций PHP (типа trigger_error) меня не интересуют, я говорил про вывод ошибок в собственных функциях.
А кто тебе мешает вызвать ошибку пользовательского типа E_USER_*, а позже её перехватить...
 

robocomp

Новичок
а чем не устраивают? Чего конкретно в этом механизме не хватает=то?

мне действительно очень интересно, потому что, как я понимаю, можно было бы все, что описано, реализовть с их помощью достаточно неплохо.
 

BeGe

Вождь Апачей, блин (c)
Не "достаточно неплохо", а очень хорошо и правильно, потому что исключения были как раз для таких вещей и придуманы.
 

atv

Новичок
Есть только два способа решения таких ситуаций. Первый - это исключения (там где они есть). Второй для тех случаев, когда нет механизма исключений - пример реализации можно найти в классе PEAR.php. Несколько раздутый (на мой взгляд), но охватывает все возможные решения. Идея использования похожа на исключения. Там где потенциально "опасный" код заключается в try/catch, во втором варианте регистрируется callback функция, которая способна справиться с возможной ошибкой. Или можно оставить всё как есть и перехватывать все ошибки в стандартном обработчике.
 

white phoenix

Новичок
Ну у меня скорей автоматизированная передача debug-информации, и её перехват. Исключения немного для другого.
 

atv

Новичок
...чтобы скрипт который использует данную библеотеку мог максимально удобно получить оповещение о произошедшей ошибке (например об отсоеденении от сервера), и сделать соответствующие действия...
а это кто писал? :)

Опять же, разве дебаг-информация существует отдельно от ошибки.

В своём скрипте перед вызовом функций библиотеки назначаеш обработчик ошибок, если ошибка произойдёт, твой обработчик перехватит её и получит всю необходимую информацию (см. PEAR)
 

white phoenix

Новичок
atv
> Опять же, разве дебаг-информация существует отдельно от ошибки.
Далеко не всегда, чаще всего они нераздельны.
> В своём скрипте перед вызовом функций библиотеки назначаеш обработчик ошибок, если ошибка произойдёт,
> твой обработчик перехватит её и получит всю необходимую информацию (см. PEAR)
Спасибо, посмотрю, но я уже написал свою штуковину.
 

robocomp

Новичок
>Спасибо, посмотрю, но я уже написал свою штуковину.

Сотри её!
 
Сверху