delphiindybad-requestdelphi-10.4-sydneyidhttp

Handle custom Error message on Bad request


I'm developing an Android app (Client). The server works with C#. When I make some request specifically some Posts, I'm getting an error message on bad request such as 'HTTP/1.1 404 Not Found' which is okay when the item I searched for is incorrect. But on bad request the server sends me also a message body in JSON, something like this:

  {
    "responseMessage":"The item you searched not found"
  }

Is there a way to get this message (and NOT the bad request message 'HTTP/1.1 404 Not Found') and show it as a response of bad request? The back end works fine, I check it on Postman. My code of Post request is this:

  Json := '{ '+
          ' "code":"'+str+'",'+
          ' "userid":'+userid+''+
          ' } ';
  JsonToSend := TStringStream.Create(Json, TEncoding.UTF8);
  try
   IdHTTP1.Request.ContentType := 'application/json';
   IdHTTP1.Request.CharSet := 'utf-8';

   try

   sResponse := IdHTTP1.Post('http://....', JsonToSend);

   except      
       on e  : Exception  do
        begin
             ShowMessage(e.Message); // this message is : HTTP/1.1 404 Not Found
             Exit;
        end;

   end;

  finally
  JsonToSend.Free;
  end;

Solution

  • To receive the JSON content on errors, you have 2 options:

    1. Catch the raised EIdHTTPProtocolException and read the JSON from its ErrorMessage property, not the Message property:

      try
        sResponse := IdHTTP1.Post(...);
      except      
        on E: EIdHTTPProtocolException do
        begin
          sResponse := E.ErrorMessage;
        end;
        on E: Exception do
        begin
          ShowMessage(e.Message);
          Exit;
        end;
      end;
      
    2. Enable the hoNoProtocolErrorException and hoWantProtocolErrorContent flags in the TIdHTTP.HTTPOptions property to prevent TIdHTTP.Post() from raising EIdHTTPProtocolException on HTTP failures, and instead just return the JSON to your sResponse variable. You can use the TIdHTTP.ResponseCode property to detect HTTP failures, if needed:

      IdHTTP1.HTTPOptions := IdHTTP1.HTTPOptions + [hoNoProtocolErrorException, hoWantProtocolErrorContent];
      
      try
        sResponse := IdHTTP1.Post(...);
        if IdHTTP1.ResponseCode <> 200 then ...
      except      
        on E: Exception do
          ...
      end;