Форум: "Основная";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];
ВнизОбработка ошибок или как работает Except Найти похожие ветки
← →
КаПиБаРа © (2005-03-09 08:22) [0]Имеется код
procedure TForm1.Button1Click(Sender: TObject);
begin
try
with TForm2.Create(self) do
try
DoSomefing;
finally
Free;
end;
except
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
raise Exception.Create("Ошибка в onCreate");
end;
procedure TForm2.DoSomefing;
begin
raise Exception.Create("Ошибка в методе DoSomefing");
end;
Объясните почему появляется сообщение "Ошибка в onCreate", а "Ошибка в методе DoSomefing" не появляется. Почему второе сообщение не появляется я заю, но почему появляется первое? В чем отличие механизма подавления первой и второй ошибки?
← →
Александр Иванов © (2005-03-09 08:36) [1]До кода, где появляется вторая ошибка просто не доходит дело. По шагам пройдись и увидишь. А различие между finally и except в том, что первый не обрабатывает исключение, код из него выполняется всегда и ошибка переходит для обработки на следующий уровень.
← →
КаПиБаРа © (2005-03-09 08:41) [2]Александр Иванов © (09.03.05 8:36) [1]
Неа... доходит.
← →
Digitman © (2005-03-09 08:43) [3]событие TForm.OnCreate возникает в контексте конструктора формы автоматически сразу после успешного завершения конструирования всех компонентов, "брошенных" на эту форму в дизайн-тайм
поскольку в теле обработчика TForm.OnCreate возбуждается необрабатываемое исключение, объект-форма не создается (точнее - экз-р тут же разрушается), а управление передается на блок except
← →
КаПиБаРа © (2005-03-09 08:50) [4]Digitman © (09.03.05 8:43) [3]
Я или тупой или у меня объект создается, т.к. кодprocedure TForm2.DoSomefing;
begin
ShowMessage(Caption);
raise Exception.Create("Ошибка в методе DoSomefing");
end;
выводит название формы "Да зраствует 1 мая!";
← →
Digitman © (2005-03-09 09:00) [5]
> КаПиБаРа © (09.03.05 08:50) [4]
сначала
> Почему второе сообщение не появляется я заю
а теперь уже
> код
> procedure TForm2.DoSomefing;
> begin
> ShowMessage(Caption);
> raise Exception.Create("Ошибка в методе DoSomefing");
> end;
как это понимать ?
то "выводится" оно у тебя, то не "выводится" ...
← →
sniknik © (2005-03-09 09:02) [6]
procedure TForm1.Button1Click(Sender: TObject);
begin
with TForm2.Create(self) do
try
DoSomefing;
finally
Free;
end;
end;
и все будет
← →
КаПиБаРа © (2005-03-09 09:14) [7]Переделал код что бы было более понятно.
procedure TForm1.Button1Click(Sender: TObject);
begin
try
with TForm2.Create(self) do
try
DoSomefing;
finally
Free;
end;
except
ShowMessage("Что то случилось!");
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
raise Exception.Create("Ошибка в onCreate");
end;
procedure TForm2.DoSomefing;
begin
ShowMessage(Caption);
raise Exception.Create("Ошибка в методе DoSomefing");
end;
Описание тестирования:
Запускаю файл Project1.exe
На главной форме нажимаю кнопку.
Появляется окно с заголовком "Project1", краным крестиком, кнопкой ОК и сообщением "Ошибка в onCreate.".
Нажимаю на ОК.
Появляется окно с заголовком "Project1", кнопкой ОК и сообщением "Да здравствует первое мая!" (это и есть заголовок Form2).
Нажимаю на ОК.
Появляется окно с заголовком "Project1", кнопкой ОК и сообщением "Что то случилось!".
Нажимаю на ОК.
Закрываю приложение.
Выводы и вопросы:
Выходит метод DoSomefing все таки вызывается и Exception генерируемый в нем гасится моим try except, а почему все таки не гасится Except в OnCreate?
← →
КаПиБаРа © (2005-03-09 09:26) [8]Или так:
procedure TForm1.Button1Click(Sender: TObject);
begin
try
with TForm2.Create(self) do
try
DoSomefing;
finally
Free;
end;
except
on E: Exception do ShowMessage("Что то случилось! " + E.Message);
end;
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
raise Exception.Create("Ошибка в onCreate");
end;
procedure TForm2.DoSomefing;
begin
ShowMessage(Caption);
raise Exception.Create("Ошибка в методе DoSomefing");
end;
Описание тестирования:
Запускаю файл Project1.exe
На главной форме нажимаю кнопку.
Появляется окно с заголовком "Project1", краным крестиком, кнопкой ОК и сообщением "Ошибка в onCreate.".
Нажимаю на ОК.
Появляется окно с заголовком "Project1", кнопкой ОК и сообщением "Да здравствует первое мая!" (это и есть заголовок Form2).
Нажимаю на ОК.
Появляется окно с заголовком "Project1", кнопкой ОК и сообщением "Что то случилось! Ошибка в методе DoSomefing".
Нажимаю на ОК.
Закрываю приложение.
Выводы и вопросы:
Выходит метод DoSomefing все таки вызывается и Exception генерируемый в нем гасится моим try except, а почему все таки не гасится Except в OnCreate?
← →
Digitman © (2005-03-09 09:36) [9]
> КаПиБаРа © (09.03.05 09:14) [7]
падон .. в случае с формой ее объект в дан.случае не разрешается
необработанное тобой исключение передается на обработку объекту Application, и в нем, если ты не назначил обработчик OnException, просто вызывается метод ShowException (выводящий сообщение об исключении), исключение "гасится" (raise там не вызывается)
← →
КаПиБаРа © (2005-03-09 09:42) [10]Digitman © (09.03.05 9:36) [9]
В каком месте этот код можно посмотреть, а то я что то искал, но найти не мог.
← →
KSergey © (2005-03-09 09:46) [11]> [7] КаПиБаРа © (09.03.05 09:14)
> Переделал код что бы было более понятно.
> Описание тестирования:
Вот это все больше похоже на правду, чем изначальный вопрос.
Дело в том, что пользовательский обработчик OnCreate формы в VCL покрыт try/except с полным подавлением исключения.
Таким образом, если даже в обработчике OnCreate происходит исключение - выводится сообщение - но дальше все идет своим чередом. Зачем - мне не понятно.
Для примера попробуйте перекрыть AfterConstruction, например (никто тогда ничего госить не будет) - и поведение сразу изменится (перенести туда функциональность из OnCreate)
← →
КаПиБаРа © (2005-03-09 09:47) [12]Digitman © (09.03.05 9:36) [9]
И еще вопрос. Зачем сделана эта хитрость с передачей исключения объекту Application?
Невозмжность погасить внешним try except исключение в методе onCreate введена с каким то умыслом или это побочный эффект при работе какой-то схемы обработки исключений?
← →
KSergey © (2005-03-09 09:48) [13]> [10] КаПиБаРа © (09.03.05 09:42)
> Digitman © (09.03.05 9:36) [9]
Что касается момента, описанного Digitman - см. реализацию Application.Run
← →
Digitman © (2005-03-09 10:08) [14]
> КаПиБаРа © (09.03.05 09:47) [12]
> каком месте этот код можно посмотреть
это - модуль Forms
см. реализацию метода TCustomForm.DoCreate, в теле которого кака раз и вызывается метод Application.HandleException
> Зачем сделана эта хитрость с передачей исключения объекту
> Application?
видимо, Борланд дает тем самым тебе возможность централизованной обработки искл.ситуаций, потенциально возникающих при конструировании форм
в OnException, если ты обрабатываешь это событие, ты волен либо принять какие-то спецмеры по устранению причин исключения (форма при этом не разрушается) либо выбросить исключение наружу, вызвав для него raise (форма будет уничтожена)
по дифолту, если ты не обрабатываешь OnException, Борланд просто сообщит диал.окном о факте возникшего и погашенного им исключения, после чего конструирование формы продолжит свое выполнение штатным образом
← →
КаПиБаРа © (2005-03-09 10:41) [15]Digitman ©
KSergey ©
Спасибо.constructor TCustomForm.Create(AOwner: TComponent);
begin
GlobalNameSpace.BeginWrite;
try
CreateNew(AOwner);
if (ClassType <> TForm) and not (csDesigning in ComponentState) then
begin
Include(FFormState, fsCreating);
try
if not InitInheritedComponent(Self, TForm) then
raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
finally
Exclude(FFormState, fsCreating);
end;
if OldCreateOrder then DoCreate;
end;
finally
GlobalNameSpace.EndWrite;
end;
end;
procedure TCustomForm.DoCreate;
begin
if Assigned(FOnCreate) then
try
FOnCreate(Self);
except
if not HandleCreateException then
raise;
end;
if fsVisible in FFormState then Visible := True;
end;
function TCustomForm.HandleCreateException: Boolean;
begin
Application.HandleException(Self);
Result := True;
end;
Еще вопрос:
Зачем HandleCreateException оформлен в виде функции, если он возвращает всегда True?
← →
Digitman © (2005-03-09 10:49) [16]
> Зачем HandleCreateException оформлен в виде функции, если
> он возвращает всегда True?
этот protected-метод - динамический.
ты вправе перекрыть его в любом своем наследнике и тем самым реализовать нужную тебе логику
например, если перекрыть этот метод вот так
function TForm2.HandleCreateException: Boolean;
begin
Result := False;
end;
то все твои вопросы сразу отпадут
← →
КаПиБаРа © (2005-03-09 10:55) [17]Digitman © (09.03.05 10:49) [16]
Спасибо.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.05 c