Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Общий обработчик ошибок, завершающий программу.


И. Павел ©   (2010-06-28 09:53:00) 

Здравствуйте.

Я хочу, чтобы все необработанные ошибки в моей программе завершали ее работу.
Для этого я написал такой обработчик Application.OnException:
procedure TForm1.OnE(Sender: TObject; E: Exception);
begin
 try
 //обработка ошибки
 except
 end;
 halt;
end;

И присваиваю его перед run:
Application.OnException := Form1.OnE;
Application.Run;

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

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

Попытался разобраться в коде метода TApplication.HandleException – но там вызов OnE произойдет только, если  “if ExceptObject is Exception then”, а иначе вызовется SysUtils.ShowException…Что это за ошибки такие: not (ExceptObject is Exception) и все ли они приводят к завершению программы?

Заранее спасибо.


Игорь Шевченко   (2010-06-28 16:35:00) [1]


> а дойдет ли тут до ексепта?


куда денется ? скомпилируй, запусти, оно даже возбудится


Leonid Troyanovsky   (2010-06-28 16:02:00) [2]


> sniknik ©   (28.06.10 15:54) [12]

> > если пользователь решит написать raise TForm1.Create?
> а дойдет ли тут до ексепта? скорее еще компилятор "зарубит".

Доходит (D6).
И автоматически удаляется после обработки "исключения".

--
Regards, LVT.


И. Павел   (2010-06-28 15:59:00) [3]

> Leonid Troyanovsky ©

Спасибо.


> sniknik ©

Да, это я параметр забыл :)


sniknik   (2010-06-28 15:54:00) [4]

> если пользователь решит написать raise TForm1.Create?
а дойдет ли тут до ексепта? скорее еще компилятор "зарубит".


Leonid Troyanovsky   (2010-06-28 15:51:00) [5]


> И. Павел ©   (28.06.10 15:37) [10]

> Они все пройдут в if ExceptObject is Exception then ...,
>  тоесть else написан только на тот случай, если пользователь
> решит написать raise TForm1.Create?

Видимо, так :)
Но, главное, что б ничего из исключений не терялось.

--
Regards, LVT.


И. Павел   (2010-06-28 15:37:00) [6]

> Сформулируй ясней, можно с примером.
>Достаточно просто не вызывать ее.

Все ошибки в run попадают в HandleException.

procedure TApplication.HandleException(Sender: TObject);
begin
 if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
 if ExceptObject is Exception then
 begin
   if not (ExceptObject is EAbort) then
     if Assigned(FOnException) then
       FOnException(Sender, Exception(ExceptObject))
     else
       ShowException(Exception(ExceptObject));
 end else
   SysUtils.ShowException(ExceptObject, ExceptAddr);
end;


Они все пройдут в if ExceptObject is Exception then ..., тоесть else написан только на тот случай, если пользователь решит написать raise TForm1.Create?


Leonid Troyanovsky   (2010-06-28 15:12:00) [7]


> Leonid Troyanovsky ©   (28.06.10 15:04) [8]

> в дельфийские (потомки Exception) при uses SysUtils, ЕМНИП.

Про uses я погнал, sorry, но, все равно, не то, про что спрашивали.

> И. Павел ©   (28.06.10 14:57) [7]

Сформулируй ясней, можно с примером.

--
Regards, LVT.


Leonid Troyanovsky   (2010-06-28 15:04:00) [8]


> И. Павел ©   (28.06.10 14:57) [7]

> А сама система внутри run генерирует только потомки exception?

Переобоснуй.
Если имеется ввиду RTL, то она транслирует системные исключения
в дельфийские (потомки Exception) при uses SysUtils, ЕМНИП.

--
Regards, LVT.


И. Павел   (2010-06-28 14:57:00) [9]

> А зачем ее перекрывать? Достаточно просто не вызывать ее.

А сама система внутри run генерирует только потомки exception?


Leonid Troyanovsky   (2010-06-28 14:33:00) [10]


> И. Павел ©   (28.06.10 14:30) [5]

> Но все же мне кажется странным обработка ошибок неизвестных
> классов просто путем вывода сообщения: SysUtils.ShowException(ExceptObject,
>  ExceptAddr); И, похоже, никак эту штуку не перекрыть...

А зачем ее перекрывать? Достаточно просто не вызывать ее.

--
Regards, LVT.


И. Павел   (2010-06-28 14:30:00) [11]

> Ну, можно еще ExceptProc.

Спасибо.
Но перед и после run, кажется, и так при ошибке программа закрывается, а внутри run все ошибки application перехватывает.
Но все же мне кажется странным обработка ошибок неизвестных классов просто путем вывода сообщения: SysUtils.ShowException(ExceptObject, ExceptAddr); И, похоже, никак эту штуку не перекрыть...


Leonid Troyanovsky   (2010-06-28 12:11:00) [12]


> И. Павел ©   (28.06.10 11:48) [3]

> В частности, я хочу к каждой ошибке от ADODataSet.Open и
> ADOCommand.Execute прибавить еще и указатель на ADO-объект
> (чтобы при ошибке можно было посмотреть запрос, который
> к ней привел).

В ApplicationEvents.OnException он и так есть: Sender: TObject.

> возникает только в консольных программах и вне блока run

Ну, можно еще ExceptProc.

--
Regards, LVT.


И. Павел   (2010-06-28 11:48:00) [13]

> Кроме производных EAbort и только в течении Run.

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


> Непонятно, зачем менять класс и терять исходную информацию.

В частности, я хочу к каждой ошибке от ADODataSet.Open и ADOCommand.Execute прибавить еще и указатель на ADO-объект (чтобы при ошибке можно было посмотреть запрос, который к ней привел). При этом класс старой ошибки я, наверное, тоже сохраню.


> как показывает моя практика - нет

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


Leonid Troyanovsky   (2010-06-28 11:04:00) [14]


> И. Павел ©   (28.06.10 09:53)  

> Application.OnException := Form1.OnE;

Проще пользоваться TApplicationEvents.

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

Непонятно, зачем менять класс и терять исходную информацию.

> Подскажите, пожалуйста, гарантирует ли эта запись, что абсолютно
> все ошибки в программе приведут к ее завершению,

Кроме производных EAbort и только в течении Run.

> не успеет обработаться какое-нибудь посланное ранее сообщение

Не успеет.

--
Regards, LVT.


12   (2010-06-28 10:36:00) [15]

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

как показывает моя практика - нет


> Попытался разобраться в коде метода TApplication.HandleException
> – но там вызов OnE произойдет только, если  “if ExceptObject
> is Exception then”, а иначе вызовется SysUtils.ShowException…
> Что это за ошибки такие: not (ExceptObject is Exception)
> и все ли они приводят к завершению программы?

как показывает моя практика - нет


Наверх

Титульная страница Поиск, карта сайта Написать письмо