Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
6-1236668556
К
2009-03-10 10:02
2011.04.24
EIdConnClosedGracefully Connection Closed Gracefully


15-1293701642
12
2010-12-30 12:34
2011.04.24
Произношение комплексного числа. По каким буквам "ударять"?


15-1294807250
Xmen
2011-01-12 07:40
2011.04.24
переход в DevExpress


1-1252579314
webpauk
2009-09-10 14:41
2011.04.24
тень


1-1252655548
plato
2009-09-11 11:52
2011.04.24
Изменяемые компоненты формы хранить в плагинах или ...?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский