Обработка исключений и лишний код
Модератор: Модераторы
-
SovNarKom
- постоялец
- Сообщения: 389
- Зарегистрирован: 28.05.2005 10:37:39
- Откуда: Воронеж [vrn] [36]
- Контактная информация:
Обработка исключений и лишний код
Хочу поднять на обсуждение данную проблему:
Модуль SysUtils ставит свои обработчики всевозможных исключений, кроме того, в визуальном режиме используются также всплывающие окна, с предложениями либо закрыть либо продолжить работу... ну я думаю понятно...
Это довольно удобная штука, однако в приложениях более менее требующих фирменного стиля, эти окна сразу бросаются в глаза, не говоря уж о том, что во многих случаях удобнее было бы обрабатывать исключения полностью вручную и возможно без уведомления пользователя окнами.
Использование try/except/finally отчасти снимает эту проблему, но не до конца, да и не нравится мне эта система вцелом... но это уже дело вкуса, зато код, отвечающий, за окна остаётся...
В общем, интересно узнать ваше мнение по этому поводу, и идеи по решению этой проблемы. И если уж не удаления лишнего кода(по крайней мере мне это предславляется возможным при серьёзных модификациях LCL, а этим врятли кто-то будет заниматься в ближайшее время), то идеи по поводу ручной обработки были бы интересными.
Сам сполгода назад пытался ради интереса... кое что удалось перенаправить, но не всё, одним словом результат меня не устроил... А вот сейчас опять понадобилось, но уже серьёзно.
Модуль SysUtils ставит свои обработчики всевозможных исключений, кроме того, в визуальном режиме используются также всплывающие окна, с предложениями либо закрыть либо продолжить работу... ну я думаю понятно...
Это довольно удобная штука, однако в приложениях более менее требующих фирменного стиля, эти окна сразу бросаются в глаза, не говоря уж о том, что во многих случаях удобнее было бы обрабатывать исключения полностью вручную и возможно без уведомления пользователя окнами.
Использование try/except/finally отчасти снимает эту проблему, но не до конца, да и не нравится мне эта система вцелом... но это уже дело вкуса, зато код, отвечающий, за окна остаётся...
В общем, интересно узнать ваше мнение по этому поводу, и идеи по решению этой проблемы. И если уж не удаления лишнего кода(по крайней мере мне это предславляется возможным при серьёзных модификациях LCL, а этим врятли кто-то будет заниматься в ближайшее время), то идеи по поводу ручной обработки были бы интересными.
Сам сполгода назад пытался ради интереса... кое что удалось перенаправить, но не всё, одним словом результат меня не устроил... А вот сейчас опять понадобилось, но уже серьёзно.
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
-
SovNarKom
- постоялец
- Сообщения: 389
- Зарегистрирован: 28.05.2005 10:37:39
- Откуда: Воронеж [vrn] [36]
- Контактная информация:
Да конечно, во многих случаях использовать try/except довольно удобно и приятно, но возьмём например такой случай:
Существует программа и дллка, программа циклически вызывет те или иные процедуры библиотеки, библиотека вообще сторонняя, в ней произойти может всё что угодно.
Можно поставить try/except вне цикла вызова, можно при каждом вызове(тут возникает побочный вопрос о влиянии try на произаодительность).
При первом же исключении, пусть это будет серьёзное исключение, какое-то AV, сработает обработчик, можно будет произвести аварийное закрытие программы и т.д.
А вот другой случай:
Библиотека каким то образом запортит данные программы, что чаще всего и бывает с самыми труднообнаружимыми ошибками... Цикл благополучно отработает. Спустя некоторое время начнёт выполняться код с данными, которые никто в try сажать не будет, и вот тут то и случится непредвиденное...
Выход я так понимаю - засадить всё приложение в try/except? Тогда в случае excepta, не обработанного внутри по любому придётся завершать работу... чтож в принципе да - нормальный подход. Попробую сейчас такое организовать...
Sergei I. Gorelkin
А событие всё-всё будет перехватывать, или некоторые типы исключений? А то просто я припосинаю, что там их явно больше 3-х.
Существует программа и дллка, программа циклически вызывет те или иные процедуры библиотеки, библиотека вообще сторонняя, в ней произойти может всё что угодно.
Можно поставить try/except вне цикла вызова, можно при каждом вызове(тут возникает побочный вопрос о влиянии try на произаодительность).
При первом же исключении, пусть это будет серьёзное исключение, какое-то AV, сработает обработчик, можно будет произвести аварийное закрытие программы и т.д.
А вот другой случай:
Библиотека каким то образом запортит данные программы, что чаще всего и бывает с самыми труднообнаружимыми ошибками... Цикл благополучно отработает. Спустя некоторое время начнёт выполняться код с данными, которые никто в try сажать не будет, и вот тут то и случится непредвиденное...
Выход я так понимаю - засадить всё приложение в try/except? Тогда в случае excepta, не обработанного внутри по любому придётся завершать работу... чтож в принципе да - нормальный подход. Попробую сейчас такое организовать...
Sergei I. Gorelkin
А событие всё-всё будет перехватывать, или некоторые типы исключений? А то просто я припосинаю, что там их явно больше 3-х.
- shade
- энтузиаст
- Сообщения: 879
- Зарегистрирован: 21.02.2006 19:15:48
- Откуда: http://shamangrad.net/
- Контактная информация:
Помоему исключения нормально работают до тех пор, пока dll-ка не пытается обрабатывать исключения. Вообще динамически загружаемые библиотеки не должны использовать обработку исключений - т.к. не известно какая прога будет ее использовать и как она будет обрабатывать исключения: не думаю, что RTL FPC обрадуется приходу исключения от RTL C++, если вообще сможет его поймать...
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
SovNarKom писал(а):А событие всё-всё будет перехватывать, или некоторые типы исключений? А то просто я припосинаю, что там их явно больше 3-х.
Будет перехватывать все, что возникло внутри цикла обработки сообщений, т.е. после вызова Application.Run. Исключения, возникшие на этапах инициализации и завершения приложения, туда не попадают.
Кстати, все приложение уже находится внутри try..except - на уровне модуля System. Из-за этого в случае падения мы видим сообщение об RTE, а не (в виндах) предложение отправить отчет в M$.
-
MylnikovDm
- постоялец
- Сообщения: 103
- Зарегистрирован: 15.02.2007 20:26:10
- Откуда: Челябинск
Я вот одного не пойму, ну зачем было описывать процедуру как of object... чтобы к какому нибудь объекту прицеплять?... По-моему было бы лучше простую процедуру... ну да ладно.
of object потому, что это общепринятое объявление для методов класса. От обычного процедурного типа отличается тем, что при его вызове будет передаваться скрытый параметр self, указывающий на экземпляр класса, который производит вызов.
Кстати, при этом вовсе не обязательно перекрывать класс TApplication. Можете объявить соответсвующий метод в любом из классов, хоть в той же главной форме приложения, а потом подставить его вместо Application.OnException.
При этом "правила хорошего тона" предполагают, что указатель на старый метод сохраняется внутри вашего класса и он вызывается во всех тех случаях, которые вы сами не обрабатываете.
Это довольно удобная штука, однако в приложениях более менее требующих фирменного стиля, эти окна сразу бросаются в глаза, не говоря уж о том, что во многих случаях удобнее было бы обрабатывать исключения полностью вручную и возможно без уведомления пользователя окнами.
Если вы пишите "фирменное приложение", то по большому счёту в нем сообщения об ошибках у пользователя вообще возникать не должны. А те сообщения об исключительных ситуациях, вызыванных либо его действиями, либо дествиями других программ или ОС должны быть вами обработаны и вы как разработчик должны решить, что в этом случае следует делать. то ли спрашивать пользователя, то ли самому как-то обходить поблему. По большому счёту встроенные окна сообщений расчитаны именно на разработчиков для режима отладки.
Лично на мой взгляд для решения данных проблем возможностей конструкции try\except\finally хватает на 95%. Другое дело, что сложность разработки "защищённой" программы при этом возрастает в разы. Ну так тем действительно фирменная программа и отличается от кустарной поделки.
А вот другой случай:
Библиотека каким то образом запортит данные программы, что чаще всего и бывает с самыми труднообнаружимыми ошибками... Цикл благополучно отработает. Спустя некоторое время начнёт выполняться код с данными, которые никто в try сажать не будет, и вот тут то и случится непредвиденное...
Да уж, подобные проблемы с dll вегда сложно отлавливать. Но тут уж либо не использовать библиотек, которые портят данные программы, либо втсраивать в программу защитные механизмы, чтобы она могла обнаружить, что данные были испорчены. Именно по этой причине в тех местах, где это не слишком обременительно или очень важно я всегда проверяю корректность входных данных, чтобы программа лишний раз не показывала пользователям сообщения, в которых он всё равно ни черта не поймёт.
А с дрйго стороны, подобное поведение библиотеки возможно либо если она плохо отлажена (не используйте подобные библиотеки), либо вы сами подали ей на вход не совсем корректные данные (нужно внимательнее читать документацию к библитекам и тщательнее проверять корректность передаваемых данных). Причём мой личный опыт говорит о том, что второй вариант встречается всё таки гораздо чаще, чем первый.
-
SovNarKom
- постоялец
- Сообщения: 389
- Зарегистрирован: 28.05.2005 10:37:39
- Откуда: Воронеж [vrn] [36]
- Контактная информация:
MylnikovDm
Ну... могли бы и не писать так много, мысль то уже ясна.
А вот тут не соглашусь, причём вообще. Исходя из личного опыта смело заявляю, что невозможно написать сложную многокомпонентную систему, без возможных ошибок такого рода. Кроме того во многих случаях всё зависит от оборудования клиента, не говоря уже о просто различных сбоях. И если произойдёт такой сбой, который при хорошо работающем оборудовании произойти был не должен, то следует его как можно более информативно проинформировать о существующих проблемах.
Ну... могли бы и не писать так много, мысль то уже ясна.
Если вы пишите "фирменное приложение", то по большому счёту в нем сообщения об ошибках у пользователя вообще возникать не должны.
А вот тут не соглашусь, причём вообще. Исходя из личного опыта смело заявляю, что невозможно написать сложную многокомпонентную систему, без возможных ошибок такого рода. Кроме того во многих случаях всё зависит от оборудования клиента, не говоря уже о просто различных сбоях. И если произойдёт такой сбой, который при хорошо работающем оборудовании произойти был не должен, то следует его как можно более информативно проинформировать о существующих проблемах.
- alexs
- долгожитель
- Сообщения: 4069
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
произойдёт такой сбой, который при хорошо работающем оборудовании произойти был не должен, то следует его как можно более информативно проинформировать о существующих проблемах.
На мой взгляд - оператору лучше просто сказать что произошла ошибка
а вот всю подробную информацию зписать в файл протокола
на экран всё равно всего чего надо не выведеш - слишком много
и многие операторы имеют привычку закрыват информационные сообщения не читая - потом от них просто невозможно добиться что там было.
-
SovNarKom
- постоялец
- Сообщения: 389
- Зарегистрирован: 28.05.2005 10:37:39
- Откуда: Воронеж [vrn] [36]
- Контактная информация:
alexs
Да, абсолютно согласен, поэтому и написал в своё время пару модулей, которые должны всю работу на себя были брать, и можно было дописать класс, для обработки сообщения нужным способом. от вывода на экран, до посылки по почте например.
А вот в Lazarus натнулся на сложности... поэтому аопрос и возник...
Сейчас всё понятно стало.
Да, абсолютно согласен, поэтому и написал в своё время пару модулей, которые должны всю работу на себя были брать, и можно было дописать класс, для обработки сообщения нужным способом. от вывода на экран, до посылки по почте например.
А вот в Lazarus натнулся на сложности... поэтому аопрос и возник...
Сейчас всё понятно стало.
-
MylnikovDm
- постоялец
- Сообщения: 103
- Зарегистрирован: 15.02.2007 20:26:10
- Откуда: Челябинск
А вот тут не соглашусь, причём вообще. Исходя из личного опыта смело заявляю, что невозможно написать сложную многокомпонентную систему, без возможных ошибок такого рода. Кроме того во многих случаях всё зависит от оборудования клиента, не говоря уже о просто различных сбоях. И если произойдёт такой сбой, который при хорошо работающем оборудовании произойти был не должен, то следует его как можно более информативно проинформировать о существующих проблемах.
Мы, похоже, говорим о разных вещах.
Согласен, что системы и пользователи этих систем бывают разные. Но вот только ответье честно, какое количество информации из стандартного сообщения Windows, когда "программа выполнила недопустимую операцию", лично вам понятна и полезна для решения возникших проблем? Вот эти все регистры и масса шестнадцатиричных цифр о чём может сообщить пользователю?
Даже мне, разработчику программы, если у меня нет при этом запущенного отладчика, все эти значения регистров ни о чём не говорят. А ведь те же пользователи периодически норовят мне всунуть листок бумаги, на который они аакуратно перпеисали всю информаицю из такого окна.
Другими словами, я лишь хотел сказать о том, что те сообщения, которые должны поялвятся для пользователя системы, должны ну очень отличатся от тех, которые по умолчанию выдаются стандартной библиотекой. А это значит, что большую часть из них придётся обработать самому вручную (ну или разработать свой механизм обработки с той же записью в log-файл, как предлагалось выше).
-
betatester
- постоялец
- Сообщения: 276
- Зарегистрирован: 27.04.2007 22:21:45
- Контактная информация:
