Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.05.24;
Скачать: CL | DM;

Вниз

Re-raise исключений   Найти похожие ветки 

 
It's not me   (2009-03-18 13:35) [0]

При выполнении конструктора некоего класса может произойти исключение номер 1.
Класс пытается выполнять некие действия, которые также могут привести к исключению номер 2. Данное исключение номер 2 обрабатывается нормально и предсказуемо. Но как бы отменить создание объекта по исключению номер 1?

То есть:

constructor TMy.Create;
begin
 try
   <работаем работаем работаем>
 except on E1:Exception do
   try
     <Пытаемся исправить ситуацию>;
   except on E2:Exception do
     <не получилось...>
     <как re-raise"нуть E1?>
   end;
 end;
end;


 
It's not me   (2009-03-18 13:39) [1]

Можно, конечно, просто сгенерировать abort. Но это как последний вариант.

Хотелось бы, чтобы код, создающий данный класс, имел информацию о том исключении, которое привело к невозможности создания класса.


 
Palladin ©   (2009-03-18 13:39) [2]

Raise;


 
Palladin ©   (2009-03-18 13:41) [3]

хотя вру... конструкция дикая...
зачем пытаться исправлять ситуацию в блоке except ?


 
Empleado ©   (2009-03-18 13:43) [4]

raise E1.Create?


 
test ©   (2009-03-18 13:51) [5]

Что то никаких идей кроме
FreeAndNil(Self)
но помойму это бред.


 
Плохиш ©   (2009-03-18 14:01) [6]

raise E1;


 
It's not me   (2009-03-18 14:15) [7]


> хотя вру... конструкция дикая...


предложи лучше


> зачем пытаться исправлять ситуацию в блоке except ?


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


> Что то никаких идей кроме
> FreeAndNil(Self)
> но помойму это бред.


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


> raise E1.Create?


ты меня спрашиваешь? Я не знаю... )))


> raise E1;


так можно делать, это нормально?
Спасибо!


 
Palladin ©   (2009-03-18 14:21) [8]

constructor TMy.Create;
var
e1e:Exception;
begin
try
  <работаем работаем работаем>
 e1e:=Nil;
except on E1:Exception do e1e:=e1;
end;

If e1e<>Nil Then
 try
   <Пытаемся исправить ситуацию>;
  e1e:=Nil;
 except
 end;

If e1e<>Nil Then Raise e1e;
end;


 
Сергей М. ©   (2009-03-18 14:36) [9]


> It"s not me   (18.03.09 13:35)  


Как-то так:

var
 exptobj: Exception;
..
try
  <работаем работаем работаем>
except on E1:Exception do
begin
  exptobj := Exception(AcquireExceptionObject);
  try
    <Пытаемся исправить ситуацию>;
    ReleaseExceptionObject;
  except on E2:Exception do
    <не получилось...>
    raise excptobj;
  end;
 end;
end;


 
test ©   (2009-03-18 14:43) [10]

It"s not me   (18.03.09 14:15) [7]
Извени великий учитель не признал, ты просто оставь пустые try except и все сам же обьяснял.


 
It's not me   (2009-03-18 14:55) [11]

Palladin, абсолютно не понял, чем конструкция лучше. Ты просто ввел лишнюю переменную, удлинил код и убрал вложенность кода. А смысл?

Было:

constructor TMy.Create;
begin
try
  <работаем работаем работаем>
except on E1:Exception do
  try
    <Пытаемся исправить ситуацию>;
  except Raise E1;
  end;
end;
end;


стало:

constructor TMy.Create;
var
e1e:Exception;
begin
try
 <работаем работаем работаем>
e1e:=Nil;
except on E1:Exception do e1e:=e1;
end;

If e1e<>Nil Then
try
  <Пытаемся исправить ситуацию>;
 e1e:=Nil;
except
end;

If e1e<>Nil Then Raise e1e;
end;


ты считаешь твой код читабельнее? Хз, чем оперировать постоянно с e1e, мне читабельнее кажется мой код.


 
Palladin ©   (2009-03-18 15:00) [12]


> It"s not me   (18.03.09 14:55) [11]

Я тебе ничего не навязываю. Дело лично твое.


 
It's not me   (2009-03-18 15:00) [13]


> Как-то так:


ммм... А чем плох код:

constructor TMy.Create;
begin
 try
   <работаем работаем работаем>
 except on E1:Exception do
   try
     <Пытаемся исправить ситуацию>;
   except Raise E1;
   end;
 end;
end;


?


 
It's not me   (2009-03-18 15:02) [14]


> Я тебе ничего не навязываю. Дело лично твое.

дык и я тебе ничего не навязываю. Ты предложил альтернативный стиль написания одного и того же по функциональности кода. Я высказал мнение, что мой вариант мне кажется более компактным и более читабельным. Вот и все )


 
Сергей М. ©   (2009-03-18 15:02) [15]


> мне читабельнее кажется мой код


Если уж на то пошло, то в твоем варианте тоже требухи ненужной хватает - E1 и E2 совершенно лишние:

var
exptobj: Exception;
..
try
 <работаем работаем работаем>
except on Exception do
begin
 exptobj := AcquireExceptionObject;
 try
   <Пытаемся исправить ситуацию>;
   ReleaseExceptionObject;
 except on Exception do
   <не получилось...>
   raise excptobj;
 end;
end;
end;


 
test ©   (2009-03-18 15:03) [16]

Сергей М. ©   (18.03.09 15:02) [15]
Что скажешь?
type
TMy=class
  private
    constructor Create;
end;
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

function GetMy():TMy;
var
 Form1: TForm1;

implementation

uses ConvUtils;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
x:TMy;
begin
x := GetMy;
try
 if x = nil then
   Memo1.Lines.add("nil");
except
 on e:Exception do
   Memo1.Lines.add(e.Message);
end;
end;

{ TMy }

constructor TMy.Create;
begin
 inherited Create;
end;

function GetMy: TMy;
begin
try
  Result := TMy.Create;
  RaiseConversionError("&#194;&#241;&#229; &#239;&#235;&#238;&#245;&#238;");
except
  Result := nil;
end;
end;

end.


 
Сергей М. ©   (2009-03-18 15:15) [17]


> test ©   (18.03.09 15:03) [16]


Скажу - лажа.

Мемлик гарантирован.


 
It's not me   (2009-03-18 15:35) [18]


> Если уж на то пошло, то в твоем варианте тоже требухи ненужной
> хватает - E1 и E2 совершенно лишние:


в моем варианте [13] требухи в виде E2 просто нету.

E1 есть, но с тем же успехом я могу сказать, что у тебя лишнее объявление:

var
exptobj: Exception;


В твоем варианте явное объявление exptobj. А в моем варианте неявное объявление E1. Монописуально, ты так не считаешь? )))

test, перестань смешить людей. Ну ты реально написал бред в виде FreeAndNil(Self) в конструкторе. Понятно, что тем самым ты хотел освободить занятую экземпляром класса к тому времени память.

Но ты, видимо, не знаешь, что при возникновении необработанного исключения в конструкторе - дельфи автоматически очищает выделенную к тому времени память и создание объекта отменяется. Поэтому вместо FreeAndNil(Self) можно просто написать Abort; и его не обработать.

Но это в вопросе даже не спрашивалось, этот факт просто подразумевался. Вопрос был совершенно о другом, а не как остановить создание объекта.
Вместо того, чтобы признать свои пробелы в знаниях, ты решил продолжить финтить ушами. Почитай лучше литературу, всяко полезнее.


 
Сергей М. ©   (2009-03-18 16:15) [19]


> в моем варианте [13]


Зато в [0] есть.
А то что ты в [13] "доточил" свой же код в [0], то в чем тогда был смысл топикстарта ?


 
Сергей М. ©   (2009-03-18 16:20) [20]


> При выполнении конструктора некоего класса


А фиолетово в конструкоре это происходит или не в конструкторе.

Ежу понятно что исключение, выброшенное в конструкторе (неважно какое и какого уровня вложенности обработки), приведет к несозданию объекта.

Ты для кого, спрашивается, делал это никому не нужное уточнение, г-н агрессивный ?)


 
test ©   (2009-03-18 16:27) [21]

It"s not me   (18.03.09 15:35) [18]
С тобой никто не говорит ты все точки над и расставил, форум/ветка не твоя собственность так что, я тебя игнорю ты меня идилия.

Сергей М. ©   (18.03.09 16:15) [19]

Буду думать.))


 
Сергей М. ©   (2009-03-18 16:35) [22]


> test ©   (18.03.09 16:27) [21]


> Буду думать


А что тут думать ?
Тут пилить надо)

function GetMy: TMy;
begin
try
 Result := TMy.Create; //<-- предположим, тут объект успешно создан (ресурсы под него выделены)
 RaiseConversionError("&#194;&#241;&#229; &#239;&#235;&#238;&#245;&#238;"); //<-- хрясь исключение !
except
 Result := nil; <-- попадаем сюда, нилим результат и преспокойненько возвращаем управление вызывающему коду
end;
end;

// а вот собссно и он
procedure TForm1.Button1Click(Sender: TObject);
var
x:TMy;
begin
x := GetMy; //<-- получили нил
try
if x = nil then //бесполезная проверка, ибо GetMy у тебя всегда вернет нил
  Memo1.Lines.add("nil"); //вряд ли это вызовет исключение
except
// сюда никогда не попадем
on e:Exception do
  Memo1.Lines.add(e.Message);
end;
end;


 
It's not me   (2009-03-18 17:02) [23]


> Ты для кого, спрашивается, делал это никому не нужное уточнение


для Test"а, который как ты не заметил в посте номер [5] предложил в конструкторе писать FreeAndNil(Self).

А за выдачу сугубо личного мнения о "ненужности" уточнения за общественное - зачот. Характеризует )


 
Сергей М. ©   (2009-03-18 17:15) [24]


> для Test"а


Test (С) в топикстарте никаким боком еще не фигурировал, а упоминание конструктора было тобой сделано уже там, так что не гони уже пургу)


> о "ненужности" уточнения


А оно действительно ненужное)

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


 
Игорь Шевченко ©   (2009-03-18 17:31) [25]

Питер, а ты вообще нафига сюда ходишь ? У тебя проблемы с общением, или еще с чем ?
Просто интересно...


 
Anatoly Podgoretsky ©   (2009-03-18 19:44) [26]

> It"s not me  (18.03.2009 14:15:07)  [7]

> А зачем вообще пытаться исправлять ошибки?

Правильно незачем, вот я и не исправляю.


 
vuk ©   (2009-03-18 20:59) [27]

Непонятная тема. Исклиючния в конструкторе обрабатывать нафиг не надо. Деструктор нужно писать так, чтобы он отрабатывал нормально даже тогда, когда конструктор осыпался по исключению. Вот и весь сказ. Собственно, это в справке написано всё.


 
Сергей М. ©   (2009-03-18 21:14) [28]


> vuk ©   (18.03.09 20:59) [27]


Конструктор тут вообще ни причем, это он его всуе приплёл для "пущей важности проблемы".
Та же самая "проблема" с теми же самыми решениями точно так же применима и к обычной регулярной процедуре или ф-ции и к любому другому методу объекта.


 
vuk ©   (2009-03-18 21:24) [29]

А не надо всуе приплетать, т.к. ситуации разные получаются. :)


 
Сергей М. ©   (2009-03-18 21:44) [30]


> vuk ©   (18.03.09 21:24) [29]


Ну вот загорелось ему рерайзить E1 в момент обработки E2 !
Ну и пусть себе рерайзит, благо проблема высосана из пальца.


> как бы отменить создание объекта по исключению номер 1?


Да хоть по номер столохматому !

Цитирую самого себя:

> Ежу понятно что исключение, выброшенное в конструкторе (неважно
> какое и какого уровня вложенности обработки), приведет к
> несозданию объекта


Но автор явно не ёж, потому как шибко беспокоится, что объект останется неразрушенным, если какое-то там исключение (по барабану какое) в конструкторе не будет там же и погашено.


 
It's not me   (2009-03-18 23:09) [31]


> Исклиючния в конструкторе обрабатывать нафиг не надо. Деструктор
> нужно писать так, чтобы он отрабатывал нормально даже тогда,
>  когда конструктор осыпался по исключению. Вот и весь сказ.
>  Собственно, это в справке написано всё

не догнал...

Если конструктор осыпался по исключению, то создающий экземпляр класса внешний код просто не получит ссылку на этот собственно экземпляр класса. Соответственно, никак и деструктор не сможет вызвать (разве что над nil, а это уже разруливает free)... Поясни плиз.


 
It's not me   (2009-03-18 23:13) [32]


> потому как шибко беспокоится, что объект останется неразрушенным

опять ты, г-н Гений, решаешь за меня о чем я беспокоюсь.

Ежу понятно, что любое исключение в конструкторе приведет к несозданию объекта. Беспокоюсь я не об этом, а о том, какие исключение выплюнется во внешний код при несоздании объекта. И в моем случае гораздо лучше выплевывать исключение по E1, которое реально и привело к невозможности создать объект, чем исключение E2, которое лишь побочка от попыток разрулить исключение E1 и может только запутать внешний код, если он обрабатывает исключения.


 
It's not me   (2009-03-18 23:16) [33]


> Если конструктор осыпался по исключению, то создающий экземпляр
> класса внешний код просто не получит ссылку на этот собственно
> экземпляр класса

ну имеется в виду, конечно, классическое создание объекта через TClassType.Create, а не махинации со всякими InitInstance.


 
Плохиш ©   (2009-03-18 23:22) [34]


> It"s not me   (18.03.09 23:09) [31]
>
>


> Если конструктор осыпался по исключению, то создающий экземпляр
> класса внешний код просто не получит ссылку на этот собственно
> экземпляр класса. Соответственно, никак и деструктор не
> сможет вызвать (разве что над nil, а это уже разруливает
> free)... Поясни плиз.
>

Ты бы почитал для начала чего...


 
Германн ©   (2009-03-19 00:07) [35]


> благо проблема высосана из пальца.
>

+1


 
Palladin ©   (2009-03-19 00:13) [36]


> It"s not me  (18.03.09 23:09) [31]

если в конструкторе класса возникает исключение, то автоматически вызывается деструктор конструируемого объекта
и кстати для этих случаев придуман free


 
Palladin ©   (2009-03-19 00:19) [37]

а по поводу ловли исключения именно на этапе создания (не в самом конструкторе, а именно выше уровнем) я знаю только один класс где иногда нужно это делать - TFileStream


 
vuk ©   (2009-03-19 00:35) [38]

to It"s not me   (18.03.09 23:09) [31]:
>Поясни плиз.
Что пояснять-то? При обломе в конструкторе деструктор вызывается автоматически. Проверяется элементарно. Отладчик в помощь. И справку читать про конструкторы и деструкторы.


 
Сергей М. ©   (2009-03-19 08:31) [39]


> Беспокоюсь я не об этом, а о том, какие исключение выплюнется
> во внешний код


Какое выплюнешь, такое и выплюнется.

Но это твое


> как бы отменить создание объекта


не имеет к выплевыванию какого-то конкретно интересующего тебя исключения ни малейшего отношения.


 
Rouse_ ©   (2009-03-19 09:58) [40]

А я бы переписал всю конструкцию...
ну или уволил бы разработчика, умудрившегося написать код, который два раза подряд может влететь в исключение...



Страницы: 1 2 вся ветка

Текущий архив: 2009.05.24;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.01 c
2-1239550339
Новичок
2009-04-12 19:32
2009.05.24
Помогите обратиться к параметрам FilterOptions


2-1239083759
Нов_и_чок
2009-04-07 09:55
2009.05.24
Экспорт DBF в MDB


2-1239018375
Summer
2009-04-06 15:46
2009.05.24
Нажатие мышью в TChart


2-1239179296
bioss
2009-04-08 12:28
2009.05.24
Работа с интерфейсом в Delphi


15-1236982065
вопро про кладовку
2009-03-14 01:07
2009.05.24
А что с кладовкой? Ничего не скачать, не посмотреть нельзя.