За последние 24 часа нас посетили 48475 программистов и 1729 роботов. Сейчас ищут 680 программистов ...

Часто ли вы используете обработку ошибок (try, throw,catch)?

Тема в разделе "Прочее", создана пользователем alex455, 27 июл 2011.

  1. alex455

    alex455 Активный пользователь

    С нами с:
    27 май 2011
    Сообщения:
    63
    Симпатии:
    0
    Имеет ли смысл это изучать? В каких ситуациях исключения лучше отображения ошибок самим PHP?
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Исключения - это такая штука, что только в PHP является экзотикой, а в нормальный ООП языках - это одно из основных средств, так что изучать однозначно надо.
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    alex455
    В каких ситуациях исключения лучше отображения ошибок самим PHP?
    только во время разработки, может быть. Вобще выводить ошибки пользователю - бессмысленное занятие :D
     
  4. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Да ладно.
    index.php:
    PHP:
    1. <?php
    2. try {
    3. /* весь код */
    4. } catch {
    5. /* универсальный шаблон сообщения о ошибке, текст ошибки извлекаем из exception */
    6. }
    грубо говоря, внутри одного try можно выполнять любой код, и где-бы не случился throw, пользователь увидит стандартное сообщение, ЕСЛИ этот exception не будет перехвачен раньше (некоторые ошибки надо не пользователю показывать, а обрабатывать как отказ операции).
    Это прекрасный механизм
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    блин. все что я сказал относится ко второй половине фразы - отображение ошибок. я туплю.
     
  6. karlozzz

    karlozzz Активный пользователь

    С нами с:
    24 окт 2010
    Сообщения:
    430
    Симпатии:
    0
    Адрес:
    Y-OLA
    Да вы что хоть, какое отображение ошибок... Исключения - отличный инструмент обработки ошибок внутри программы, скажем есть ф-я, которая да нет выдает, ей передается проксик, handler pdo или mysql (может не хендлек конечно, не помню точно), суть в том, что при ошибке с подключением к нету или ошибкой с базой, или еще какой то ошибкой выдавать исключение, которое и на наследнике реализовано быть может, а перехватывать и обрабатывать его можно в любом месте, где выполняется ф-я, был проект, где в доках к каждой ф-и был написан набор исключений, которые выдавать она может, при этом если ф-я выполняет другую, которая выдает искл-я, то она может их обрабатывать и в соответствии с этим либо продолжать выполняться, либо выдавать собственные исключения, либо пробрасывать выше пришедшие исключения... Вывод - исключения - замечательная вещь, весь вопрос где они критины, а где нет, в идеале, я думаю, они должны быть в каждом проекте, но это слишком трудоемко (например исключение если вдруг во время вып-я скрипта база перестала отвечать)...

    МБ немножк неграмотно написал, быстро писал прост
     
  7. karakh

    karakh Активный пользователь

    С нами с:
    11 дек 2007
    Сообщения:
    1.344
    Симпатии:
    0
    Re: Часто ли вы используете обработку ошибок (try, throw,cat

    Да, я часто использую try-catch. Да, это имеет смысл изучать. Обработка лучше отображения ошибок самим PHP практически во всех случаях.

    Собственно, такого выбора нет. Есть выбор между 1) обработкой исключений через try/catch, 2)подавлением сообщений об ошибках и обработкой полученного некорректного результата и 3) использованием set_exception_handler.
     
  8. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Механизму исключений в РНР ещё многому нужно научиться.
    Выглядит красиво, а по факту имеем:

    1. Перехват фатальных ошибок с помощью register_shutdown_function
    2. Перехват некритичных ошибок set_error_handler
    3. Передача исключений из самой жопы с помощью set_exception_handler

    Вкупе с неправильной архитектурой останется только купить попкорн и наслаждаться.
    А так - сюрпризов будет куча. Не смог РНР обратиться к функции по религиозным причинам (будем расставлять везде function_exists ради throw?) - курим в сторонке. Никто нас эксепшнами не побалует.
     
  9. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Это не механизму PHP нужно многому научиться, а "программистам" повзрослеть. Функция у них делать куда-то, ага.
     
  10. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Ты работал когда-нибудь с кодом, который сам не писал?
    Тогда очень странно читать то, что ты пишешь =)
     
  11. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Какое отношение эксепшены имеют к коду, "который сам не писал"?

    У эксепшенов есть четкое назначение - передача вверх информации об фатальной ошибке бизнес-логики, а всякие "забытые" функции и прочее производящее фатальную ошибку исполнения php кода к эксепшенам отношения не имеет. Последние вообще обрабатывать на уровне своего приложения стоит только в одном случае - если нужно нарисовать полное сообщение об ошибке с трекингом стека вызовов. В реальном приложении ошибка php кода - это кривые руки, что не исправляется. А вот ошибка бизнес-логики, часто, может быть проанализирвана и проигнорирована выше.
     
  12. KMB

    KMB Активный пользователь

    С нами с:
    9 сен 2011
    Сообщения:
    63
    Симпатии:
    0
    Никогда не использую. В правильно написанной программе не должно возникать подобных ошибок.
     
  13. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    а как же ошибки "отказ базы данных" или "нет места на диске"? программа не должна их учитывать?
     
  14. KMB

    KMB Активный пользователь

    С нами с:
    9 сен 2011
    Сообщения:
    63
    Симпатии:
    0
    А разве без try, catch их не отследить, disk_free_space уже отменили?
     
  15. alive342

    alive342 Активный пользователь

    С нами с:
    21 апр 2011
    Сообщения:
    137
    Симпатии:
    0
    Адрес:
    Российская Федерация
    в php почти не использую
    но в том же питоне без исключений никуда )
     
  16. KMB

    KMB Активный пользователь

    С нами с:
    9 сен 2011
    Сообщения:
    63
    Симпатии:
    0
    Питона не знаю, поэтому ничего сказать не могу. Но если там действительно без исключений никуда, то это плохо. Плох тот язык, в котором постоянно приходится обрабатывать ошибки. Имхо, разумеется.
     
  17. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    отследить, но что делать с этим результатом?

    одно дело где-то вначале выполнения написать
    PHP:
    1. <?php
    2. try {
    3. //blablabla
    4. } catch (Exception $e) {
    5. // красивое сообщение пользователю "Попробуйте снова через 5 секунд" с записью в лог "что-то не так" и сообщением админу
    6. }
    другое в каждой функции писать
    PHP:
    1. <?php if (0 != ($result = doSomething()) {
    2. return $result;
    3. } else {
    4. // blabla
    5. }
     
  18. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    KMB
    вы бы как-нибудь аргументировали свою точку зрения, ссылки на статьи бы привели. А если это, вдруг, плод ваших мыслей, то тогда тем более ждём разгромной статьи на тему "правильно написанные программ", будет очень интересно просветиться.
     
  19. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    try...catch - жутко удобная штука. Если правильно использовать.
    Для себя вижу следующие плюсы
    1) Обработка ошибок сосредоточена в одном месте.
    2) Дополнительная возможность управления ходом выполнения - разные типы исключений можно обрабатывать по-разному, и опять же - всё в одном месте.
     
  20. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Знал бы где упадешь - солому бы постелил ;)
    try-catch это и есть солома, потому что заранее неизвестно ничего.
    А вдруг вытащат жесткий диск сис-админы во время копирования файла? И че тогда? =))
    Вызовем функцию check_disk_ejected() ?
     
  21. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    теперь всегда.

    core/loader.php

    PHP:
    1. <?php
    2.  
    3. error_reporting ( E_ALL );
    4.  
    5. $sCoreDir = rtrim ( realpath ( dirname ( __FILE__ ) ), DIRECTORY_SEPARATOR );
    6.  
    7. date_default_timezone_set ( 'Europe/Moscow' );
    8.  
    9. require_once $sCoreDir . '/autoload.php';
    10. require_once $sCoreDir . '/exception.php';
    11.  
    12. function WRXErrorHandler($errno, $errstr, $errfile, $errline) {
    13.  
    14.     switch ($errno) {
    15.         case E_USER_ERROR :
    16.             $sError = 'UERROR';
    17.             break;
    18.         case E_USER_DEPRECATED :
    19.             $sError = 'UDEPRECATED';
    20.             break;
    21.         case E_USER_WARNING :
    22.             $sError = 'UWARNING';
    23.             break;
    24.         case E_USER_NOTICE :
    25.             $sError = 'UNOTICE';
    26.             break;
    27.         case E_NOTICE :
    28.             $sError = 'ENOTICE';
    29.             break;
    30.         case E_ERROR :
    31.             $sError = 'EERROR';
    32.             break;
    33.         case E_WARNING :
    34.             $sError = 'EWARNING';
    35.             break;
    36.         case E_PARSE :
    37.             $sError = 'EPARSE';
    38.             break;
    39.         case E_NOTICE :
    40.             $sError = 'ENOTICE';
    41.             break;
    42.         default :
    43.             $sError = 'UNKNOWN';
    44.             break;
    45.     }
    46.     throw new WRXException ( "WRX $sError($errno): $errstr", 0, $errfile, $errline );
    47.     return false;
    48. }
    49.  
    50. function WRXExceptionHandler(WRXException $Exception) {
    51.  
    52.     ob_end_clean();
    53.  
    54.     print ('<pre>') ;
    55.     print ("\nWRX Exception: [" . $Exception->getCode () . "] " . $Exception->getMessage ()) ;
    56.     print ("\nWRX Exception: [" . $Exception->getFile () . "(" . $Exception->getLine ()) . ")]";
    57.     print ("\n") ;
    58.     print ("\n" . $Exception->getTraceAsString ()) ;
    59.  
    60. }
    61.  
    62. function WRXFatalErrorHandler($buffer) {
    63.  
    64.     if (preg_match ( "/Fatal error: (.+)/", $buffer, $regs )) {
    65.  
    66.         return "<pre>WRX FATAL: " . $regs [1];
    67.     }
    68.     return $buffer;
    69. }
    70.  
    71. set_error_handler ( 'WRXErrorHandler', E_ALL );
    72. set_exception_handler ( 'WRXExceptionHandler' );
    73. ob_start ( "WRXFatalErrorHandler" );
    74.  
    75. WRXCore::getInstance ();
    76.  
    core/exception.php

    PHP:
    1. <?php
    2.  
    3. class WRXException extends Exception {
    4.  
    5.     public function __construct($sMessage, $iCode = 0, $sFile = '', $iLine = 0, $ePrev = null) {
    6.  
    7.         parent::__construct ( $sMessage, $iCode , $ePrev);
    8.  
    9.         $this->file = $sFile;
    10.         $this->line = $iLine;
    11.     }
    12. }
    core/autoload.php

    PHP:
    1. <?php
    2.  
    3. define ( 'WRX_CLASS_DIR','/classes/');
    4.  
    5. function __autoload($sClassName) {
    6.  
    7.     static $sDirPath = null;
    8.  
    9.     if(is_null($sDirPath)) {
    10.         $sDirPath = rtrim(realpath ( dirname(__FILE__).'/../'),DIRECTORY_SEPARATOR).WRX_CLASS_DIR;
    11.     }
    12.  
    13.     $sNewClassName = $sClassName;
    14.     if (substr ( $sNewClassName, 0, 3 ) == 'WRX') {
    15.         $sNewClassName = substr ( $sNewClassName, 3 );
    16.     }
    17.  
    18.     $sFileName = $sDirPath . strtolower ( preg_replace ( '/([a-z])([A-Z])/', '$1/$2', $sNewClassName ) ) . '.php';
    19.  
    20.     if (file_exists ( $sFileName )) {
    21.         require_once $sFileName;
    22.     } else {
    23.         die ( "Не могу загрузить класс [" . $sClassName . "] из [" . $sFileName . "]" );
    24.     }
    25.  
    26. }
    htdocs/index.php

    PHP:
    1. <?php
    2.  
    3. require_once "../core/loader.php";
    4.  
    5. $a = $b;
    вывод

    Код (Text):
    1.  
    2. WRX Exception: [0] WRX ENOTICE(8): Undefined variable: b
    3. WRX Exception: [/usr/www/*****/htdocs/index.php(5)]
    4.  
    5. #0 /usr/www/*****/htdocs/index.php(5): WRXErrorHandler(8, 'Undefined varia...', '/usr/www/*****...', 5, Array)
    6. #1 {main}
     
  22. KMB

    KMB Активный пользователь

    С нами с:
    9 сен 2011
    Сообщения:
    63
    Симпатии:
    0
    iliavlad
    Вот-вот, "с записью в лог что-то не так", а когда вам понадобиться узнать что именно у вас не так, все равно придется в результате городить теже if (0 != ($result = doSomething())

    topas
    А что здесь аргументировать-то? Большинство функций PHP возвращают на выходе TRUE/FALSE либо код ошибки. Если это есть, значем придумывать что-то еще?

    Apple
    А вдруг завтра конец света и никакая функция вам не поможет :)))
    Я понимаю, что ошибки надо отслеживать, но не до абсурда-же это доводить.

    440Hz, какой ужас, вы что всерьез этим пользуйтесь или это просто прикол такой?
     
  23. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    KMB
    Вы отстаиваете свою точку зрения, пытаетесь переубедить X человек и при этом

    PHP:
    1. <?php
    2. ...
    3. try{
    4.     ob_start();
    5.    
    6.     header('Content-Type: text/html; charset=utf-8');
    7.     Session::auto();
    8.    
    9.     require_once 'etc/ElevantRouter.class.php';
    10.     Router::setPathClient(PATH_ROUTER);
    11.     Router::setUrl($_SERVER['REQUEST_URI']);
    12.     Router::instance('ElevantRouter');
    13.    
    14.     require_once PATH_TEMPLATE . '/wrapper.php';
    15.     ob_end_flush();
    16. }
    17. catch (RouterException $e){
    18.     ob_end_clean();
    19.     if ($e->getCode() === RouterException::NOT_FOUND_METHOD){
    20.         header('HTTP/1.0 404');
    21.         include('app/view/page404.html');
    22.         die;
    23.     }
    24.     exception_log($e);
    25. }
    26. catch (PageException $e){
    27.     ob_end_clean();
    28.     $e->handler();
    29.     die;
    30. }
    31. catch (Exception $e){
    32.     ob_end_clean();
    33.     header("HTTP/1.0 500 Internal Server Error");
    34.     include('app/view/page500.html');
    35.     exception_log($e);
    36. }
    37.  
    38. ?>
    39.  
    exception_log() в режиме отладки выводит трассировку на экран, в боевом режиме складывает ошибки в файловую систему

    Прекрасно работает.
     
  24. KMB

    KMB Активный пользователь

    С нами с:
    9 сен 2011
    Сообщения:
    63
    Симпатии:
    0
    topas, извините, может я действительно чего-то недопонимаю, но к чему все эти сложности с трассировкой, если в точности тоже самое итак автоматом пишется в лог-записи сервера? Открыл, прочел, - определил в чем проблема.
     
  25. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    KMB
    Сложностей нет, есть удобный инструмент, я им пользуюсь.

    Не всегда в контексте метода или функции удаётся понять в чём же реальная ошибка. Например метод поиска пользователя по id. Мы знаем, что id не может быть по своей природе отрицательным, но в результате обработки скрипта в этот метод пришла именно минус единица. Одного взгляда на трассировку вполне достаточно, чтобы увидеть в каком месте произошел сбой.

    Ошибки, обычно, проявляются в дочерних функциях и методах.

    По поводу логов web-сервера: не каждый веб-сервер способен хранить POST-данные и PHP-сессию. А это входные данные, без которых порою трудно воспроизвести ошибку