Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
ВнизВопрос про работу эксепшенов Найти похожие ветки
← →
cyber-pilot (2011-01-20 14:25) [0]Есть следующий код:
procedure TForm1.Button1Click(Sender: TObject);
var
vSL: TStringList;
begin
try
try
vSL.CommaText := "";
except
on E: Exception do
begin
E.Message := "Msg1: " + E.Message;
raise;
end;
end;
except
on E: Exception do
begin
E.Message := "Msg2: " + E.Message;
ShowMessage(E.Message);
raise;
end;
end;
end;
Я всегда думал, что если писать таким образом, то к сообщения будут склеиваться. В этом же случае происходит Access Violation и информация о добавленных строчка почему-то теряется. Это так специально сделано или глюк Делфи?
Проверял в Delphi 2007 и Delphi XE.
← →
Dennis I. Komarov © (2011-01-20 14:31) [1]Глюков нет. Работает так как надо.
А чего там где недоприлипло, я не понял...
← →
Palladin © (2011-01-20 14:34) [2]E уровнем ниже не есть E уровнем выше. это два разных объекта
← →
Ega23 © (2011-01-20 14:35) [3]
> Я всегда думал, что если писать таким образом, то к сообщения
> будут склеиваться.
1. Чтобы "склеивалось" делается так:try
....
except on E: Exception do
raise Exception.Create("bla-bla-bla " + E.Message);
end;
2. AV получаешь закономерно, ибо обращаешься к свойству несозданного объектаvSL.CommaText := "";
Надо так:vSL := TStringList.Create;
try
try
vSL.CommaText := "";
.....
except on E: Exception do
raise Exception.Create("bla-bla-bla " + E.Message);
end;
finally
vSL.Free;
end;
← →
cyber-pilot (2011-01-20 15:24) [4]
> Palladin © (20.01.11 14:34) [2]
>
> E уровнем ниже не есть E уровнем выше. это два разных объекта
Я всегда считал, что это один и тот же объект.
> 1. Чтобы "склеивалось" делается так:
> try
> ....
> except on E: Exception do
> raise Exception.Create("bla-bla-bla " + E.Message);
> end;
Но при этом в обработчике более высокого уровня я не смогу узнать какой тип эксепшена произошел в действительности. То есть не получится написать on EOutOfMemory do.
> 2. AV получаешь закономерно, ибо обращаешься к свойству
> несозданного объекта vSL.CommaText := "";
Это я специально написал, чтобы ошибку вызвать.
← →
Ega23 © (2011-01-20 15:27) [5]
> Но при этом в обработчике более высокого уровня я не смогу
> узнать какой тип эксепшена произошел в действительности.
> То есть не получится написать on EOutOfMemory do.
Нет проблем:try
....
except on E: Exception do
raise Exception.Create("bla-bla-bla " +#13#10 + E.ClassName + #13#10 + E.Message);
end;
← →
Palladin © (2011-01-20 15:33) [6]
> Я всегда считал, что это один и тот же объект.
я не знаю какая религия это исповедует
← →
KSergey © (2011-01-20 15:48) [7]Вопрос у меня чайника:
А вот так можно?
try
....
except on E: Exception do
E.Message := .....
raise E;
end;
← →
Ega23 © (2011-01-20 15:53) [8]А, я понял что тебе нужно.
Вроде как в общем случае решения нет. Тебе нужно чётко знать класс исключения. Что-то типа
procedure TForm4.Button1Click(Sender: TObject);
begin
try
try
ShowMessage(FloatToStr(5/StrtoInt(Edit1.Text)))
except
on E: EConvertError do raise EConvertError.Create("Первый обработчик" + #13#10 + E.Message);
on E: EZeroDivide do raise EZeroDivide.Create("Первый обработчик" + #13#10 + E.Message);
on E: Exception do raise Exception.Create("Первый обработчик (а фиг знает)" + #13#10 + E.Message);
end;
except on E: Exception do
ShowMessage("Второй обработчик" + #13#10 + E.Message);
end;
end;
← →
Ega23 © (2011-01-20 15:55) [9]
> KSergey © (20.01.11 15:48) [7]
>
> А вот так можно?
А конструктор кто вызывать будет?
← →
Palladin © (2011-01-20 15:55) [10]нет
← →
cyber-pilot (2011-01-20 15:59) [11]
> Ega23 © (20.01.11 15:53) [8]
Да, это мне и нужно. И обычно так все и работает, и доказывает, Palladin © (20.01.11 14:34) [2] - не правда.
А вот для AccessViolation не срабатывает.
← →
Palladin © (2011-01-20 16:09) [12]Не понял, что доказывает?
try
try
vSL.CommaText := "";
except
on E: Exception do
begin
E.Message := "Msg1: " + E.Message;
ShowMessage(IntToStr(Integer(E)));
raise;
end;
end;
except
on E: Exception do
begin
E.Message := "Msg2: " + E.Message;
ShowMessage(IntToStr(Integer(E)));
end;
end;
удивись
← →
Ega23 © (2011-01-20 16:10) [13]
> и доказывает, Palladin © (20.01.11 14:34) [2] - не правда.
Доказывает. Это два разных объекта одного и того же класса.
Есть класс, а есть экземпляр класса. Класс - один, экземпляров - от нуля до Over9000
Соответственно, в [8] проверяется принадлежность E к EZeroDivide и EConverError, после чего подымаются аналогичные по классу исключения.
Третий случай - для всех остальных классов, аналог else в case.
А на втором обработчике перехватываются уже любые исключения.
← →
Anatoly Podgoretsky © (2011-01-20 16:18) [14]> KSergey (20.01.2011 15:48:07) [7]
Нельзя, справа должен быть объект, а не текст.
← →
Игорь Шевченко © (2011-01-20 16:31) [15]KSergey © (20.01.11 15:48) [7]
procedure raiseOOM;
begin
raise EOutOfMemory.Create ("gothca");
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
raiseOOM;
except
on E: Exception do
begin
E.Message := "Foo";
raise E;
end;
end;
end;
← →
Ega23 © (2011-01-20 16:37) [16]
> А вот для AccessViolation не срабатывает.
EAccessViolation is raised when an application:
Dereferences a nil (Delphi) or NULL (C++) pointer.
Writes to memory reserved for executable code.
Attempts to access a memory address for which there is no virtual memory allocated to the application.
Run-time exception information is saved in fields provided by EExternal.
Note: Applications should not raise EAccessViolation directly, but should instead rely on the run time to raise this exception.
← →
DiamondShark © (2011-01-21 01:08) [17]
> Это так специально сделано или глюк Делфи?
Это специально так сделано.
Исключения, которые генерируются в ответ на аппаратные ловушки пересоздаются.
Программные исключения используют тот же экземпляр.
var
P: ^Integer;
a, b: double;
i, j: integer;
begin
P := nil;
a := 0;
b := 0;
i := 0;
j := 0;
try
try
// раскоментировать по вкусу
// raise EAccessViolation.Create("koo!"); // один и тот же экземляр
// raise Exception.Create("qwe"); // один и тот же экземляр
// i := i div j; // разные экземпляры
// writeln(i); // чтоб оптимизатор код не выкинул
// a := a / b; // разные экземпляры
// writeln(a); // чтоб оптимизатор код не выкинул
// P^ := 1; // разные экземпляры
except
on E: Exception do
begin
E.Message := "Msg1: " + E.Message;
ShowMessage(IntToStr(Integer(E)));
raise;
end;
end;
except
on E: Exception do
begin
E.Message := "Msg2: " + E.Message;
ShowMessage(IntToStr(Integer(E)));
end;
end;
end;
← →
DiamondShark © (2011-01-21 01:19) [18]
> DiamondShark © (21.01.11 01:08) [17]
Впрочем, не только аппаратные ловушки, а вообще все исключения, порождённые операционной системой.
Все эти исключения имеют базовым классом EExternal.
← →
KSergey © (2011-01-21 09:48) [19]> Игорь Шевченко © (20.01.11 16:31) [15]
Не могли бы вы сказать ответ? :)
Вроде с виду код как у меня.
Или предлагается попробовать и оценить эффект?
← →
cyber-pilot (2011-01-21 14:35) [20]
> Ega23 © (20.01.11 16:37) [16]
> DiamondShark © (21.01.11 01:08) [17]
Понятно. Спасибо!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.004 c