delphi-7indyidhttp

Indy error in Delphi 7: Undeclared identifier: 'hoWantProtocolErrorContent'


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'


Solution

  • 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 raises EIdHTTPProtocolException (the message body is available in the EIdHTTPProtocolException.ErrorMessage property). If the hoNoProtocolErrorException flag is enabled, or the ResponseCode number is specified in the request's AIgnoreReplies parameter, then no EIdHTTPProtocolException is raised, as the caller would like to process the ResponseCode manually. Normally TIdHTTP 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 target TStream 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...