When using TIdHTTP
to send GET
commands with JSON variables, sometimes the server returns me the error below:
HTTP/1.1 500 Internal Server Error
Using Insomnia for testing JSON results, I see an entire JSON response and a pretty response which clearly indicates what the problem is. I really need that the TStringStream
be filled even if the response code is not 200.
After a lot of searching, I understand that I should use HTTPOptions
with the parameters: hoNoProtocolErrorException
and hoWantProtocolErrorContent
. However, when using the hoWantProtocolErrorContent
option, I obtain the following error:
Undeclared identifier: 'hoWantProtocolErrorContent'
You are using an old version of Indy (is it the one that shipped with Delphi 7?). Delphi 7 was released in 2002, while the hoWantProtocolErrorContent
flag was introduced in 2016. Per New TIdHTTP flags and OnChunkReceived event in Indy's blog):
hoWantProtocolErrorContent: when an HTTP error response is received,
TIdHTTP
normally reads and discards the response’s message body and then raisesEIdHTTPProtocolException
(the message body is available in theEIdHTTPProtocolException.ErrorMessage
property). If thehoNoProtocolErrorException
flag is enabled, or theResponseCode
number is specified in the request'sAIgnoreReplies
parameter, then noEIdHTTPProtocolException
is raised, as the caller would like to process theResponseCode
manually. NormallyTIdHTTP
would still discard the message body, though. If this new flag is enabled, the message body will no longer be discarded, it will be saved in the caller's targetTStream
like a successful response would be. This flag is disabled by default to preserve existing behavior to discard error message bodies.
So, without the hoWantProtocolErrorContent
flag, the only way you can access the body data of an HTTP error response is to disable the hoNoProtocolErrorException
flag (it is disabled by default) and then catch the raised EIdHTTPProtocolException
exception and read its ErrorMessage
property, eg:
var
Response: TStringStream;
Response := TStringStream.Create('');
try
try
IdHTTP1.Get(url, Response);
except
on E: EIdHTTPProtocolException do
WriteStringToStream(Response, E.ErrorMessage);
end;
// use Response.DataString as needed...
finally
Response.Free;
end;
Or simpler:
var
Response: string;
try
Response := IdHTTP1.Get(url);
except
on E: EIdHTTPProtocolException do
Response := E.ErrorMessage;
end;
// use Response as needed...