Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.05.24;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.007 c
3-1221048997
Drowsy
2008-09-10 16:16
2009.05.24
Как в ХП передать вводимую строку из DBGrid-а?


10-1157121608
MixAnOL
2006-09-01 18:40
2009.05.24
Как установить OLE объект из dll в delphi


2-1239291893
SP
2009-04-09 19:44
2009.05.24
Как из cgi-приложения узнать запущены ли другие его копии?


3-1221456652
KirillRepin
2008-09-15 09:30
2009.05.24
Рисунок из БД в TImage


2-1239140033
istok
2009-04-08 01:33
2009.05.24
D2009: PAnsiChar to AnsiString





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский