Гость
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Правка Exception.Message при обработке исключения / 25 сообщений из 26, страница 1 из 2
13.12.2021, 02:48
    #40119535
Dimitry Timokhov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Коллеги, здравствуйте!

Иногда бывает задача при обработке исключения, дописать в его Message детализирующую информацию и сделать reraise.
Много лет пользуюсь таким механизмом:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
try
   ...
except
   on E:Exception do
   begin
      E.Message := E.Message+#13'(добавка)';
      raise;
   end;
end; 


Был уверен, что механизм надежный.

Но сегодня обнаружил, что такой механизм по-разному работает для разных классов исключений.

См. пример:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
procedure TForm1.Button1Click(Sender: TObject);
begin
   // Будет требуемое сообщение:
   //    Message 1 (O:\_temp\1\Unit1.pas, line 35)
   //    (добавка)
   try
      Assert(False, 'Message 1');
   except
      on E:Exception do
      begin
         E.Message := E.Message+#13'(добавка)';
         raise;
      end;
   end;
end;

type
   EMyExeption = class(Exception);

procedure TForm1.Button2Click(Sender: TObject);
begin
   // Будет требуемое сообщение:
   //    EMyExeption
   //    (добавка)
   try
      raise EMyExeption.Create('EMyExeption');
   except
      on E:Exception do
      begin
         E.Message := E.Message+#13'(добавка)';
         raise;
      end;
   end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
   // Будет сообщение:
   //    Access violation at address 004566C4 in module 'Project1.exe'. Read of address 00000000.
   // Я рассчитывал на сообщение:
   //    Access violation at address 004566C4 in module 'Project1.exe'. Read of address 00000000.
   //    (добавка)
   try
      TObject(nil).Destroy(); // специально вызываю EAccessViolation
   except
      on E:Exception do
      begin
         E.Message := E.Message+#13'(добавка)';
         raise;
      end;
   end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
   E: Exception;
begin
   // Дописал предыдущий пример через AcquireExceptionObject. 
   // Теперь всё ОК.
   //
   // Будет требуемое сообщение:
   //    Access violation at address 00456730 in module 'Project1.exe'. Read of address 00000000
   //    (добавка)
   try
      TObject(nil).Destroy(); // специально вызываю EAccessViolation
   except
      on Exception do
      begin
         E := AcquireExceptionObject();
         E.Message := E.Message+#13'(добавка)';
         raise E at ExceptAddr;
      end;
   end;
end;



ВОПРОС .
Что такого особенного в EAccessViolation, что он работает иначе, чем другие классы исключений?
Почему изменение EAccessViolation.Message, как указано выше в TForm1.Button3Click, игнорируется, тогда как в аналогичной ситуации изменение EMyExeption.Message учитывается?
Если реально есть что-то особенное в EAccessViolation, то где это описано?

Спасибо!

------
Delphi2007
...
Рейтинг: 0 / 0
13.12.2021, 03:18
    #40119537
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Dimitry Timokhov, :).

а если вместо raise; написать:
Код: pascal
1.
      raise ExceptClass(e.ClassType).Create(e.Message);


?
...
Рейтинг: 0 / 0
13.12.2021, 03:33
    #40119538
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Dimitry Timokhov
Был уверен, что механизм надежный.

Зря. Это очевидный хак, который имеет все шансы даже там, где работает - перестать в любой момент.

Dimitry Timokhov
Что такого особенного в EAccessViolation, что он работает иначе, чем другие классы исключений?

Долго объяснять словами, проще заглянуть в исходники и увидеть. Если коротко, то EAccessViolation - обёртка для виндового исключения, и в его случае объект EAccessViolation пересоздаётся во время raise.

Dimitry Timokhov
Если реально есть что-то особенное в EAccessViolation, то где это описано?

Надо просто пользоваться корректными механизмами. В данном случае это

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure X(AParam: string);
try
  ...
except
  on E: Exception do
    raise AddExceptionFooter(E, 'Параметр: %s', [AParam]);
end;

function AddExceptionFooter;
begin
  { содержимое примерное, просто показывает суть, так вряд ли откомпилируется }
  raise E.ClassType.CreateFmt(E + #13 + Footer, Params);
end;
...
Рейтинг: 0 / 0
13.12.2021, 03:34
    #40119539
Dimitry Timokhov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
ъъъъъ,

Варианты есть.
Один из вариантов с AcquireExceptionObject я привел.
Вашим вариантом не пользовался, но навскидку он тоже рабочий.

Удивительно само поведение - чем таким EAccessViolation отличается от моего класса исключения EMyException?
...
Рейтинг: 0 / 0
13.12.2021, 03:39
    #40119540
Dimitry Timokhov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
softwarer
Долго объяснять словами, проще заглянуть в исходники и увидеть. Если коротко, то EAccessViolation - обёртка для виндового исключения, и в его случае объект EAccessViolation пересоздаётся во время raise.


Вот хотелось бы это увидеть)))

Навскидку не нашел.
Правда, не так сильно искал, т.к. быстро вспомнил про AcquireExceptionObject и переписал через него.
...
Рейтинг: 0 / 0
13.12.2021, 03:40
    #40119541
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
...интересно. :)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var
  e: Exception;
begin
  try
    TObject(nil).Destroy(); 
  except
    E := AcquireExceptionObject;
    E.Message := E.Message + #13'Добавка';
    raise e;
  end;
end;
...
Рейтинг: 0 / 0
13.12.2021, 10:20
    #40119568
энди
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
А к чему все эти приключения? Автор таким образом пытается отследить какой AV у него дал ошибку? Так вроде это соверешенно по другому делается :)
...
Рейтинг: 0 / 0
13.12.2021, 11:06
    #40119579
Fr0sT-Brutal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
GetExceptionObject.CreateAVObject - тч он в самом деле особенный.

Добавление к Message интересное, как-то не обращал внимания, что оно доступно и на запись. Не сказал бы, что это хак, скорее вольность в интерфейсе, которую вряд ли станут убирать (хотя и могут)
...
Рейтинг: 0 / 0
13.12.2021, 11:57
    #40119592
Michael Longneck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
RaiseOuterException?
...
Рейтинг: 0 / 0
13.12.2021, 13:40
    #40119627
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
...
Рейтинг: 0 / 0
13.12.2021, 16:08
    #40119677
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Тут уже и без меня всё сказали:
1. EAccessViolation - обёртка вокруг аппаратного исключения. При raise; перебрасывается исходное исключение, а дельфёвая обёртка пересоздаётся в каждом блоке except.
2. raise EMyException - программное исключение, при raise; оно же и перебрасывается, обёрток нет.
3. AcquireExceptionObject - возможный обходной путь.
4. Но правильное решение - RaiseOuterException (или его аналог для старых версий RTL).
...
Рейтинг: 0 / 0
13.12.2021, 18:47
    #40119715
Dimitry Timokhov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
GunSmoker,

Век живи - век учись.
Лет 20 пользуюсь подобным механизмом и иногда удивлялся, почему AV не содержат доп. информацию.
Теперь понятно.

====

Спасибо всем, кто проявил внимание к моему вопросу.

====
Александр, вопрос в тему, если не против.

Сильно сложно начать использовать www.eurekalog.com?
Это же ваш продукт, насколько помню.

Как раз сегодня засбоил jedi при построении лога у одного из заказчиков.
Лет 20 назад взял их разработку, но, видимо, пришло время менять.
...
Рейтинг: 0 / 0
13.12.2021, 18:53
    #40119719
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Dimitry Timokhov
Сильно сложно начать использовать www.eurekalog.com?
Это же ваш продукт, насколько помню.

Я один из разработчиков, но это не мой продукт.

Насчёт "сложно" - мне, как разработчику, очевидно насколько это просто/понятно для пользователя - другой вопрос. У нас, мне кажется, достаточно подробные доки с кучей примеров. Если пользователь знаком с основами и принципами исключений в Delphi, то не думаю, что какие-то проблемы будут. А то бывают кадры, которые Range Check отключают и жалуются, что EurekaLog не ловит "исключение". Кому-то про except { тут ничего } end приходится разжёвывать.
...
Рейтинг: 0 / 0
13.12.2021, 21:05
    #40119751
Dimitry Timokhov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
GunSmoker,

Спасибо.
Мне в свое время Rouse_ хвалил Еврику.
Попробую, как разгружусь чуток.
...
Рейтинг: 0 / 0
14.12.2021, 03:04
    #40119792
northener
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Dimitry Timokhov
GunSmoker,

Сильно сложно начать использовать www.eurekalog.com?

Поверь мне Дима. Несложно ничуть.
В Эврике всё или почти всё уже сделано для простого и для продвинутого пользователя.
Это тебе говорю я, Германн с ДМ, который и не совсем программист, а просто ПШП.
Если я её освоил, то тебе-то какие проблемы?
...
Рейтинг: 0 / 0
14.12.2021, 03:36
    #40119795
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
2 GunSmoker

Пользуясь случаем, почти по сабжу:
Когда возникает exception, а в try..except делается raise нового, то в EL репорт идет нижнее(первое) исключение, а вот в EL Filters обрабатывается верхнее.
Я себе час мозг ломал в попытках понять, почему так)

В итоге решил вопрос через EurekaLogEvents ExceptionNotify - делаю костыли типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
  if (AExceptionInfo.Info.ExceptionType = 'lpException') and Assigned(AExceptionInfo.InnerException) then
  begin
    if AExceptionInfo.InnerException.Info.ExceptionType = 'EConvertError' then
    begin
      AHandle := False;
      Exit;
    end;
    //тут остальные такие же
  end;



и так фильтрую.
...
Рейтинг: 0 / 0
14.12.2021, 06:29
    #40119800
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Vizit0r,

в этом месте меня вставляет вывернутая наизнанку логика, порождающая постоянные NOT:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
{ Интерпретация ошибки ORA-3113 }
procedure Ora3113Notify(const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo;
  var AHandle: boolean;
  var ACallNextHandler: boolean);
var
  Dummy: boolean;
begin
  AHandle := not (TObject(AExceptionInfo.ExceptionObject).InheritsFrom(EOraError) and (EOraError(AExceptionInfo.ExceptionObject).ErrorCode = 3113));
  ACallNextHandler := AHandle;
  if not AHandle then CurrentUser.ConnectionError(nil, EOraError(AExceptionInfo.ExceptionObject), Dummy);
end;
...
Рейтинг: 0 / 0
14.12.2021, 13:17
    #40119919
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
softwarer, Не увидел ничего сверхъестественного.
Компактно и нормально читается. Предложи вариант лучше
...
Рейтинг: 0 / 0
14.12.2021, 13:26
    #40119923
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Vizit0r
Когда возникает exception, а в try..except делается raise нового, то в EL репорт идет нижнее(первое) исключение, а вот в EL Filters обрабатывается верхнее.
Я себе час мозг ломал в попытках понять, почему так)

Дело в том, что в RTL есть только одно исключение - то, которое выбрасывается. Поэтому к нему-то фильтры и применяются. И не только фильтры, вообще вся работа идёт с ним. Все предыдущие исключения (которые в inner сохраняются) - это уже обвес EL. Т.е. в код была специально добавлена конструкция, которая вместо текущего исключения (как это в Delphi по дефолту происходило бы) в баг репорт запишет исходное. Иными словами, это специальный случай, который обрабатывается явно.

Возможно, стоит добавить новую галку "к чему применять" в свойства фильтра?
...
Рейтинг: 0 / 0
14.12.2021, 13:55
    #40119936
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
white_nigger
Компактно и нормально читается.

Потому что эту конкретную процедуру писал я. Когда такое пишет другой программист, оно обычно вдвое толще.

white_nigger
Предложи вариант лучше

Да запросто. Задать правильный вопрос - и уйдёт необходимость имитировать 3-позиционный переключатель с помощью двух булёвых переменных.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
{ Интерпретация ошибки ORA-3113 }
procedure Ora3113Notify(const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo;
  var AExclude: boolean);
var
  Dummy: boolean;
begin
  AExclude := TObject(AExceptionInfo.ExceptionObject).InheritsFrom(EOraError) and (EOraError(AExceptionInfo.ExceptionObject).ErrorCode = 3113);
  if AExclude then CurrentUser.ConnectionError(nil, EOraError(AExceptionInfo.ExceptionObject), Dummy);
end;


вот так я предпочёл бы это написать.
...
Рейтинг: 0 / 0
14.12.2021, 14:06
    #40119938
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
Вот это
softwarer
Код: pascal
1.
TObject(AExceptionInfo.ExceptionObject).InheritsFrom(EOraError)

нельзя ли заменить вот этим?
Код: pascal
1.
AExceptionInfo.ExceptionObject is EOraError
...
Рейтинг: 0 / 0
14.12.2021, 14:21
    #40119942
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
_Vasilisk_,

раз я привожу к TObject - значит, он типа pointer. Так что так точно не получится. Почему InheritsFrom, а не is - сейчас уже точно не скажу. Возможно, что можно.
...
Рейтинг: 0 / 0
14.12.2021, 20:24
    #40120054
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
softwarer
Потому что эту конкретную процедуру писал я. Когда такое пишет другой программист, оно обычно вдвое толще.
Да ладно? Корона не жмёт? Хотя я бы перенёс на новую строчку оператор после then - стиль выработанный десятилетиями.
softwarer
вот так я предпочёл бы это написать.
Здесь вообще-то контракт другой, рефакторинг затрагивающий другие методы.
...
Рейтинг: 0 / 0
14.12.2021, 20:33
    #40120055
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
white_nigger
Корона не жмёт?

Нет, она у меня масштабируемая.

white_nigger
Здесь вообще-то контракт другой

Гениально. И зачем ты вообще задавал вопрос?
...
Рейтинг: 0 / 0
14.12.2021, 22:18
    #40120079
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Правка Exception.Message при обработке исключения
softwarer
Гениально. И зачем ты вообще задавал вопрос?
Пытался понять чем тебе реализация метода не угодила, вдруг что полезное услышу. А тебе оказывается архитектура кривовата
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Правка Exception.Message при обработке исключения / 25 сообщений из 26, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]