09-02-2020, 06:58 PM
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 File
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);
}
//---------------------------------------------------------------------------