Intereting Posts
не удалось сохранить одно изображение вместе с несколькими изображениями в codeigniter Как получить результаты в виде многомерного массива из mySQL и PHP? Woocommerce: пользовательская цена, основанная на пользовательском вводе «Строгие стандарты: только переменные должны передаваться по ссылке» error Как установить сеанс в базе данных codeigniter 3? Ошибка FOSFacebookBundle после входа в систему. Контроллер должен вернуть ответ (null) Загрузка видео на сервер с помощью PHP Функция Javascript всегда не запускается после .load Как установить PHP 7 (следующее поколение PHP) на Ubuntu Как избежать неопределенного индекса получение карт для приема динамически созданного KML-файла? как передавать данные с одной страницы html на второй в php? API MaxMind GeoIP: fseek () : поток не поддерживает поиск в geoip.inc Получить переменную сеанса magento на другой странице CakePHP RequestHandler возвращает RSS / JSON вместо HTML

Пользовательские сообщения об исключении: лучшие практики

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

Я вижу много людей, которые делают свои исключения, например:

throw new RuntimeException('MyObject is not an array') 

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

 throw new WrongTypeException('MyObject is not an array') 

Но это не дает много информации об отладке … и не приводит к принудительному форматированию с сообщением об ошибке. Таким образом, вы можете получить точно такую ​​же ошибку, создав два разных сообщения об ошибках … например, «Соединение с базой данных не удалось» против «Не удалось подключиться к db»

Конечно, если он пузырится на вершине, он будет печатать трассировку стека, которая полезна, но она не всегда говорит мне все, что мне нужно знать, и обычно мне приходится начинать стрелять с инструкциями var_dump (), чтобы обнаружить что пошло не так, и где … хотя это может быть несколько компенсировано приличным обработчиком исключений.

Я начинаю думать о чем-то вроде кода ниже, где мне требуется метатор исключения для предоставления необходимых аргументов для создания правильного сообщения об ошибке. Я думаю, что это может быть так:

  • Необходимо предоставить минимальный уровень полезной информации
  • Выдает несколько согласованных сообщений об ошибках
  • Шаблоны для сообщений об исключениях в одном месте (классы исключений), поэтому проще обновлять сообщения …

Но я вижу недостаток в том, что их труднее использовать (требуется, чтобы вы искали определение исключения), и, таким образом, может препятствовать другим программистам использовать предоставленные исключения …

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

 /** * @package MyExceptions * MyWrongTypeException occurs when an object or * datastructure is of the incorrect datatype. * Program defensively! * @param $objectName string name of object, eg "\$myObject" * @param $object object object of the wrong type * @param $expect string expected type of object eg 'integer' * @param $message any additional human readable info. * @param $code error code. * @return Informative exception error message. * @author secoif */ class MyWrongTypeException extends RuntimeException { public function __construct($objectName, $object, $expected, $message = '', $code = 0) { $receivedType = gettype($object) $message = "Wrong Type: $objectName. Expected $expected, received $receivedType"; debug_dump($message, $object); return parent::__construct($message, $code); } } 

….

 /** * If we are in debug mode, append the var_dump of $object to $message */ function debug_dump(&$message, &$object) { if (App::get_mode() == 'debug') { ob_start(); var_dump($object); $message = $message . "Debug Info: " . ob_get_clean(); } } 

Затем используется как:

 // Hypothetical, supposed to return an array of user objects $users = get_users(); // but instead returns the string 'bad' // Ideally the $users model object would provide a validate() but for the sake // of the example if (is_array($users)) { throw new MyWrongTypeException('$users', $users, 'array') // returns //"Wrong Type: $users. Expected array, received string } 

и мы могли бы сделать что-то вроде nl2br в специальном обработчике исключений, чтобы сделать что-то приятное для вывода html.

Читал: http://msdn.microsoft.com/en-us/library/cc511859.aspx#

И не упоминается ничего подобного, так что, может быть, это плохая идея …

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

В этом случае требуется не новый тип, чтобы указать его, но и лучшее сообщение об ошибке, вызвавшее его. Как таковая вспомогательная функция для:

  1. генерировать текстовую строку для размещения в исключении
  2. генерировать все исключение и сообщение

Это то, что требуется.

Подход 1 более ясный, но может привести к немного более подробному использованию, 2 – наоборот, торгуя синтаксисом терминатора для меньшей ясности.

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

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

Трассировка стека по минимуму дает вам функцию и, возможно, номер строки, поэтому вам следует сосредоточиться на предоставлении информации, из которой нелегко отработать.

Я не буду отвлекаться от рекомендаций относительно блога Krzysztof, но вот простой способ создания пользовательских исключений.

Пример:

 <?php require_once "CustomException.php"; class SqlProxyException extends CustomException {} throw new SqlProxyException($errorMsg, mysql_errno()); ?> 

Код за этим (который я где-то заимствовал, извинился перед кем бы то ни было)

 <?php interface IException { /* Protected methods inherited from Exception class */ public function getMessage(); // Exception message public function getCode(); // User-defined Exception code public function getFile(); // Source filename public function getLine(); // Source line public function getTrace(); // An array of the backtrace() public function getTraceAsString(); // Formated string of trace /* Overrideable methods inherited from Exception class */ public function __toString(); // formated string for display public function __construct($message = null, $code = 0); } abstract class CustomException extends Exception implements IException { protected $message = 'Unknown exception'; // Exception message private $string; // Unknown protected $code = 0; // User-defined exception code protected $file; // Source filename of exception protected $line; // Source line of exception private $trace; // Unknown public function __construct($message = null, $code = 0) { if (!$message) { throw new $this('Unknown '. get_class($this)); } parent::__construct($message, $code); } public function __toString() { return get_class($this) . " '{$this->message}' in {$this->file}({$this->line})\n" . "{$this->getTraceAsString()}"; } } 

См. « Как создавать иерархии исключений» в блоге Кшиштофа Квалины, соавтора «Руководства по разработке рамок».

Никогда, никогда не доверяйте пользователю «делать правильные вещи» и включать информацию для отладки. Если вам нужна информация, вам нужно собрать ее самостоятельно и сохранить ее где-нибудь там, где она доступна.

Также, как указано, если это сложно (er) что-то сделать, пользователи избегают этого делать, поэтому снова не зависят от их доброй воли и их знаний о том, что им нужно отправить.

Это мышление подразумевает метод, с помощью которого вы собираете информацию и регистрируете ее, что подразумевает использование var_dump () где-то.

Кроме того, как сказал Марк Харрисон, кнопка, облегчающая отправку сообщения об ошибке где-то, является фантастической для вас и для пользователей. Это позволяет им сообщать об ошибке. Вы (как получатель) получаете много дубликатов, но дублировать информацию лучше, чем никакой информации.

Однако добавьте много деталей, убедитесь и

  • облегчить вырезание и вставить все это, или
  • есть кнопка, которая сообщит об ошибке для них