Страница 1 из 1

Обработчик ошибок

Добавлено: 05 июл 2004, 14:44
duke
Есть программа, давольно большая , нужно сделать так чтоб где какая ошибка не произошла, выводилось мое сообщение. Как это можно устроить?

Добавлено: 05 июл 2004, 14:49
AiK
try
...
except
on e:Exception do ShowMessage('еггог' +e.Message);
end;

Добавлено: 05 июл 2004, 14:52
duke
У меня несколько модулей, что в каждом модуле ставить???

Добавлено: 05 июл 2004, 14:57
AiK
Это тебе виднее должно быть.

Добавлено: 05 июл 2004, 21:47
GOS
Я слышал что можно ошибки сразу обрабатывать, а можно переносить на уровень выше...
Что это значит?

Добавлено: 05 июл 2004, 22:02
AiK
Да то и значит, что либо просто забиваешь на обработку ошибки, либо в секции except
"возбуждаешь" ошибку по-новой. Ну или вообще новую ошибку. См. raise

Кстати, если в проекте используется VCL, то для решения поставленной задачи можно воспользоваться событием onException:

Код: Выделить всё

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnException := AppException;
end;

procedure TForm1.AppException(Sender: TObject; E: Exception);
begin
  ShowMessage('blabla' +E.Message);
  Application.Terminate;
end;

Добавлено: 05 июл 2004, 22:33
Naeel Maqsudov
duke, наверняка в Вашем приложении всего один инстанс TApplication, который собственно и называется Application. Все ошибки, которые возникли вне try...except...end (независимо от места возникновения) обрабатываются им, однако наверняка найдутся ошибки после которых, к сожалению, нельзя восстановиться. Правда в любом случае их можно поймать и попытаться что-нибудь сделать. По крайне мере легко можно вывести свой текст вместо "Access violation".

Для этого нужно сделать:
Application.OnException:=Объект.Обработчик_ошибок;

Обработчик_ошибок должент быть методом какого-нибудь объекта. Можно конечно использовать для этого форму (например главную, если она создается только один раз, и при этом первой), и тогда в обработчике FormCreate пишем:
Application.OnException:=Form1.MyHandler;
а в FormDestroy:
Application.OnException:=nil;

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

Сам метод MyHandler должет быть таким:

Код: Выделить всё

class
  T___ = ...
    ....
    procedure MyHandler(Sender: TObject; E: Exception);
    ....
  end;

...


procedure T___.MyHandler(Sender: TObject; E: Exception);
begin
  if E is EMathError then begin
    E.Message := 'Какая-то математическая ошибка';
    ...
  end else if E is EBDEError then begin
    ...
  end ...
    ...
  end;
  ... // Тут можно сделать запись в лог-файл, и т.д. и т.п.
  Application.ShowException(E);
  Application.Terminate;
end;

Добавлено: 05 июл 2004, 23:26
Naeel Maqsudov
GOS писал(а):Я слышал что можно ошибки сразу обрабатывать, а можно переносить на уровень выше...
Что это значит?
все try-except могу оказаться вызванными вложенно. Наример,

Код: Выделить всё

try
  X&#58]


Между тем в procedure TXClass.Create может тоже использоваться try-except.
[code]
try
  ...
except
  // место обработки 2
  //обработать математическую ошибку здесь
  on EMathError do HandleMathError; 
  //обработать BDE-ошибку здесь
  on EDBError do HandleBDEError; 
  //передать прочие ошибки на уровень выше (в место_обработки_1)
  else raise;
end;
Заморочки с вызовом конструктора класса TXClass я тут привел для большей иллюстративности. Однако, это правило выполняется и для просто вложенных друг в друга try-except!