Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Use TIdHttp inside TThread anonymous function doesn't raise exceptions
#3
Thanks Remy for the reply,

Yes What I want is to simulate the same thing that is being done in for instance TRestClient/TRestRequest where I get any response from the server in the received content it self without the need to catch any exceptions.
The DoHTTPErrorEvent is where I get the catched error and pass it to the memo in the main program.

As I said before this is similar to REST debugger but with Indy TidHTTP instead. So here is the whole code of the class:
I made a little change after I posted my question but I did not made any changes based on your suggestions yet.

Header


Code:
//New Events
typedef void __fastcall (__closure *THTTPErrorEvent)(UnicodeString ErrorMessage);
typedef void __fastcall (__closure *TCriticalErrorEvent)(System::Sysutils::Exception* E);
//---------------------------------------------------------------------------
class TIdHttpEx : public TIdHTTP
{
    typedef TIdHTTP inherited;

private:
//Fields
unique_ptr<TIdHTTPBody> FHTTPBody;
bool FResponseOk;
bool FHasErrorResponse;
bool FRaiseExceptionOn500;
String FLastErrorResponse;

//Events
THTTPErrorEvent FOnHTTPErrorEvent;
TCriticalErrorEvent FOnCriticalErrorEvent;

//---------------------------------------------------------------------------
protected:
virtual String __fastcall GetFullURL();

//Methods
virtual int __fastcall DoExecute(String AMethod, String AURL, TStream* AResponseContent = nullptr, TStream* ARequestContent = nullptr);

//Do Events Methods
virtual void __fastcall DoHTTPErrorEvent(String ErrorMessage);
virtual void __fastcall DoCriticalErrorEvent(System::Sysutils::Exception* E);

//---------------------------------------------------------------------------
public:
//Fields/Properties
__property unique_ptr<TIdHTTPBody> Body = {read = FHTTPBody};
__property bool ResponseOk = {read = FResponseOk};
__property String FullURL = {read = GetFullURL};

__property bool HasErrorResponse = {read = FHasErrorResponse};
__property String LastErrorResponse = {read = FLastErrorResponse};
__property bool RaiseExceptionOn500 = {read = FRaiseExceptionOn500, write = FRaiseExceptionOn500};

//Constructor / Destructor.
__fastcall TIdHttpEx(TComponent *Owner);
virtual __fastcall ~TIdHttpEx(void);

//Methods
virtual int __fastcall Execute(String AMethod, String AURL, TStream* AResponseContent, TStream* ARequestContent = nullptr);
virtual int __fastcall Execute(String AMethod, String AURL, TStrings* AResponseContent, TStrings* ARequestContent = nullptr);
virtual int __fastcall Execute(String AMethod, String AURL, String AResponseContent, String ARequestContent = "");
virtual int __fastcall Execute(String AMethod, String AURL, TJSONValue* AResponseContent, TJSONValue* ARequestContent = nullptr);
virtual int __fastcall Execute(String AMethod, String AURL);
virtual void __fastcall Clear();

//Events
__property THTTPErrorEvent OnHTTPErrorEvent = {read = FOnHTTPErrorEvent, write = FOnHTTPErrorEvent};
__property TCriticalErrorEvent OnCriticalErrorEvent = {read = FOnCriticalErrorEvent, write = FOnCriticalErrorEvent};

//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------


Code File
Code:
//---------------------------------------------------------------------------

#pragma hdrstop
#include "IdHttpEx.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TIdHttpEx::TIdHttpEx(TComponent *Owner)
    : TIdHTTP(Owner)
{
HTTPOptions = TIdHTTPOptions() >> hoWantProtocolErrorContent;
FHTTPBody.reset(new TIdHTTPBody);
FHTTPBody->IdHTTP = this;

FHasErrorResponse = false;
FRaiseExceptionOn500 = true;
FLastErrorResponse = "";
}
//---------------------------------------------------------------------------
__fastcall TIdHttpEx::~TIdHttpEx(void)
{
}
//---------------------------------------------------------------------------
int __fastcall TIdHttpEx::DoExecute(String AMethod, String AURL, TStream* AResponseContent, TStream* ARequestContent)
{
try
    {
    FHasErrorResponse = false;
    FLastErrorResponse = "";

    if (FHTTPBody->RequestStream == nullptr && ARequestContent != nullptr)
        FHTTPBody->RequestStream = ARequestContent;

    if (FHTTPBody->ResponseStream == nullptr && AResponseContent != nullptr)
        FHTTPBody->ResponseStream = AResponseContent;

    if (FHTTPBody->ResponseStream == nullptr && AResponseContent == nullptr)
        FHTTPBody->ResponseStream = new TMemoryStream;

    DoRequest( AMethod, AURL, FHTTPBody->RequestStream, FHTTPBody->ResponseStream,nullptr,-1);

    FResponseOk = (ResponseCode == 200);

    if (FHTTPBody->ResponseStream != nullptr)
        FHTTPBody->ResponseStream->Position = 0;
    }
catch (const EIdHTTPProtocolException &E)
    {
    if (FRaiseExceptionOn500)
        throw Exception(E.ErrorMessage);
    else
        {
        FLastErrorResponse = E.ErrorMessage;
        FHasErrorResponse = (FLastErrorResponse.Trim() != "");
        DoHTTPErrorEvent(FLastErrorResponse);
        }
    }
catch (Exception &E)
    {
    DoCriticalErrorEvent(&E);
//    Application->ShowException(&E);
//    ShowException(&E, nullptr);
    }

return ResponseCode;
}
//---------------------------------------------------------------------------
/*Important Methods*/
int __fastcall TIdHttpEx::Execute(String AMethod, String AURL, TStream* AResponseContent, TStream* ARequestContent)
{
return DoExecute(AMethod, AURL, ARequestContent, AResponseContent);
}
//---------------------------------------------------------------------------
int __fastcall TIdHttpEx::Execute(String AMethod, String AURL, TStrings* AResponseContent, TStrings* ARequestContent)
{
FHTTPBody->RequestStrings = ARequestContent;
int code = DoExecute(AMethod, AURL);
ARequestContent = FHTTPBody->ResponseStrings;
return code;
}
//---------------------------------------------------------------------------
int __fastcall TIdHttpEx::Execute(String AMethod, String AURL, String AResponseContent, String ARequestContent)
{
FHTTPBody->RequestText = ARequestContent;
int code = DoExecute(AMethod, AURL);
ARequestContent = FHTTPBody->ResponseText;
return code;
}
//---------------------------------------------------------------------------
int __fastcall TIdHttpEx::Execute(String AMethod, String AURL, TJSONValue* AResponseContent, TJSONValue* ARequestContent)
{
FHTTPBody->RequestJSON = ARequestContent;
int code = DoExecute(AMethod, AURL);
ARequestContent = FHTTPBody->ResponseJSON;
return code;
}
//---------------------------------------------------------------------------
int __fastcall TIdHttpEx::Execute(String AMethod, String AURL)
{
return DoExecute(AMethod, AURL);
}
//---------------------------------------------------------------------------
void __fastcall TIdHttpEx::Clear()
{
FHTTPBody->Clear();
Request->Clear();
Response->Clear();
}
//---------------------------------------------------------------------------
String __fastcall TIdHttpEx::GetFullURL()
{
return URL->URI;
}
//---------------------------------------------------------------------------
/*Do Events Methods Defs*/
void __fastcall TIdHttpEx::DoHTTPErrorEvent(String ErrorMessage)
{
if (FOnHTTPErrorEvent)
    FOnHTTPErrorEvent(ErrorMessage);
}
//---------------------------------------------------------------------------
void __fastcall TIdHttpEx::DoCriticalErrorEvent(System::Sysutils::Exception* E)
{
if (FOnCriticalErrorEvent)
    FOnCriticalErrorEvent(E);
}
//---------------------------------------------------------------------------
Reply


Messages In This Thread
RE: Use TIdHttp inside TThread anonymous function doesn't raise exceptions - by Ahmed Sayed - 09-02-2020, 06:58 PM

Forum Jump:


Users browsing this thread: 3 Guest(s)