Главная страница
    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.034 c
14-1081765401
Dmitriy O.
2004-04-12 14:23
2004.05.02
Кто имел опыт по размещению рекламы на своем сайте ?


3-1080812286
lightix
2004-04-01 13:38
2004.05.02
Переход на новую страницу в QuickReport


3-1081178285
olhovik
2004-04-05 19:18
2004.05.02
Добавление записи в файл


6-1078485027
Flounder
2004-03-05 14:10
2004.05.02
как создать нечто подобное FileSender


4-1078398468
galina
2004-03-04 14:07
2004.05.02
Проблема с библиотекой





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