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

Вниз

Исключения (Exceptions) - насколько безопасен такой код   Найти похожие ветки 

 
Mim1   (2004-04-18 12:44) [0]

В отдельном потоке у меня выпольнается http get (indy http client). При возникновении ошибки я должен передать ее в основной поток через syncronize. Делаю я это вот так.


procedure TCkgHttp.Execute;
...
begin
     try
       ...
       FIdHTTP.DoRequest(IdHTTPMethod,FRequest.URL,FRequest.SourceStream,FResponse.ResultStream);
       ...
     except
       on e: exception do
         begin
           FResponse.HaveError := true;
           FResponse.ErrorClassName := e.ClassName;
           FResponse.ErrorMessage := e.Message;
           FResponse.ErrorClassType := e.ClassType;
         end;
     end;
 ...
 Synchronize(ReturnData);
end;


А в основном потоке обрабатываю так


var e:Exception;
begin
 ...
       if ro.Response.HaveError then
         begin
           e := exception(ro.Response.ErrorClassType.Create);
           e.Message := ro.Response.ErrorMessage+lb+
             "Server say: "+
             ro.Response.ErrorServerSay;
           raise e;
         end;
 ...
end;


Такой код работает и ошибок не замечено(однако это не значит что их нет).

Вопрос. Насколько это безопасно, ведь конструктор класса Exception имеет параметр - текст сообщение, а вызывая конструктор без этого параметра я вызываю конструктор предка.

Может имеет смысл вызывать вместо приведенного кода следующий

           raise Exception.Create(
             "ClassName: "+
             ro.Response.ErrorClassName+lb+
             "Message: "+
             ro.Response.ErrorMessage+lb+
             "Server say: "+
             ro.Response.ErrorServerSay);

однако в таком случае я теряю некоторую информацию о классе и тп.


 
Digitman ©   (2004-04-18 12:53) [1]

все значительно проще и изящнее можно реализовать

посмотри как доп.поток может "красиво" передать инф-цию об объекте исключения осн.потоку (по версии Борланда)

модуль  SConnect.pas
метод TTransportThread.Execute


 
VMcL ©   (2004-04-18 12:54) [2]

TThread.FatalException не подойдет?


 
Mim1   (2004-04-18 13:03) [3]

Digitman ©   (18.04.04 12:53) [1]

Спасибо.
Там райзица эксцепшен созданый в потоке. То есть вместо создания нового (такогоже) как у меня можно райзить старый exception.
Наверное сделаю так же...


 
Mim1   (2004-04-18 13:05) [4]

VMcL ©   (18.04.04 12:54) [2]

Нет, это вообще не из той оперы.


 
Mim1   (2004-04-18 14:04) [5]

Digitman

Еще раз спасибо.

Значится сделал так


     try
       ...
     except
       FResponse.HaveError := true;
       FResponse.ExceptionObjInstance := AcquireExceptionObject;
     end;


Без AcquireExceptionObject ничего хорошего бы не вышло.
Если делаю on e:exception do FResponse.ExceptionObjInstance := e;  происходит av так как обьект e разрушается при выходне за пределы try блока, и ссылка на него не действительна.

В основном потоке делаю так

       if ro.Response.HaveError then
         begin
           e := ro.Response.ExceptionObjInstance;
           if e = nil then
             e := exception.Create("??????????? ?????? ??? ?????????? http ???????");
           e.Message := e.Message+lb+
             "Server say: "+
             ro.Response.ServerSay;
           raise e;
         end;


 
Digitman ©   (2004-04-18 14:17) [6]


> Mim1   (18.04.04 14:04) [5]


что-то ты не то говоришь...

ты рассматривал лок. процедуру внимательно ?

 procedure SynchronizeException;
 var
   SendException: TObject;
 begin
   if RaiseList <> nil then //не пуст ли список объетов, отражающих контексты искл-й ?
   begin
     SendException := PRaiseFrame(RaiseList)^.ExceptObject; //взяли "верхушку"
     PRaiseFrame(RaiseList)^.ExceptObject := nil; // эта строчка не дает возможности try-блоку разрушить объект-исключение
     if Assigned(FTransport) and (SendException is ESocketConnectionError) then
       FTransport.Connected := False; // это - "прикладной" уровень, можешь исключить его из рассмотрения
     PostMessage(FParentHandle, THREAD_EXCEPTION, 0, Integer(Pointer(SendException))); //здесь мы передаем ссылочку на объект-исключение осн.потоку - отныне он ответственен за обработку и уничтожение объекта-исключения
   end;
 end;


 
Mim1   (2004-04-18 15:56) [7]

Digitman ©   (18.04.04 14:17) [6]

У меня Delphi 7


 procedure SynchronizeException;
 var
   SendException: TObject;
 begin
   SendException := AcquireExceptionObject;
   if Assigned(FTransport) and (SendException is ESocketConnectionError) then
     FTransport.Connected := False;
   PostMessage(FParentHandle, THREAD_EXCEPTION, 0, Integer(Pointer(SendException)));
 end;


У тебя наверное версия delphi другая.



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

Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.035 c
6-1076015637
DDS
2004-02-06 00:13
2004.05.02
О том как добавить свой пункт в меню IE?


6-1078420166
Delpher_Gray
2004-03-04 20:09
2004.05.02
Склеивание пакетов, избежание при этом ошибок


3-1080982304
sssss
2004-04-03 12:51
2004.05.02
Create Table


3-1081162922
}|{yk
2004-04-05 15:02
2004.05.02
Group by для union


11-1064221574
RA
2003-09-22 13:06
2004.05.02
BitBtn картинка





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