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

Вниз

Исключения (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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.037 c
1-1081745917
Mva
2004-04-12 08:58
2004.05.02
Экспорт в Excell


14-1081088912
Гаврила
2004-04-04 18:28
2004.05.02
Постоянная работа для программера в Москве


7-1079437536
dik
2004-03-16 14:45
2004.05.02
Последовательный порт


14-1081172092
geg
2004-04-05 17:34
2004.05.02
Как определить чего ты стоишь как программист.


6-1077816770
rrew
2004-02-26 20:32
2004.05.02
TServerSocket &amp; ClientSocket