11
votes

How can I check for the target URL for specific response code like 200 OK without Indy throwing all sorts of exceptions out. ConnectionTimeout,ConnectionClosedGracefully, etc...

For example if URL is not proper or its host cannot be found or cannot be reached. Indy will still rise exceptions even though i tried to ignore them.

So my question is how to properly ignore these exceptions.

2
Try to be more specific with your problem. Are you working with the TIdHTTP ? If so, then you have TIdHTTP.ResponseCode available.TLama
@TLama i mean by ignoring exceptions at runtime. Exceptions are still thrown at runtime aswell.. ICS is completely silent..Santos Oliveira
You must handle them, since Indy is driven by exceptions.TLama
@TLama Well how? I don't want my thread to exit because of an exception so how to ignore it?Santos Oliveira

2 Answers

36
votes

1. How to ignore all exceptions thrown by the TIdHTTP ?

To handle all exceptions and, as you say, ignore them, you may use the code that is almost identical to the code from @Stijn's answer:

procedure TForm1.Button1Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
begin
  IdHTTP := TIdHTTP.Create;
  try
    try
      IdHTTP.Get('http://www.example.com');
    except
      // do just nothing here, if you really want to completely ignore all 
      // exceptions thrown from inside the try..except block execution and
      // if you don't want to indicate somehow, that the exception occured
    end;
  finally
    IdHTTP.Free;
  end;
end;

2. How to handle specific exceptions thrown by the TIdHTTP ?

Maybe one day you'll want to react somehow on certain types of exceptions thrown by TIdHTTP class, e.g. react only on HTTP protocol exceptions. And that's what I'll try to elaborate here.

Indy defines many exception classes for different occasions, that may occur when a certain action fails. Here is a list of exception classes, that you might be interested in when you're working with HTTP protocol:

  1. EIdException - it is the base exception class used by Indy library. It might be useful for you when you want to distinguish between exceptions raised by Indy and all other exceptions thrown by your application.

  2. EIdSocketError - from a HTTP protocol abstraction point of view it's a low level exception class, which covers all exceptions raised when a certain socket operation fails. This can be useful for you to detect, that there is something wrong at your network level.

  3. EIdConnClosedGracefully - exceptions raised by this class indicate, that the server side closed the connection with the client in a common way. This can be useful when you'd need to react to this situation, e.g. by reconnecting to the server.

  4. EIdHTTPProtocolException - this exception class is used for exceptions thrown, when an error occurs during processing of a HTTP response for a certain request. This generally happens, when an unexpected numeric HTTP response code is received from the HTTP response. It can be useful, when you want to handle HTTP protocol errors specifically. By this exception handling, you can e.g. react on certain HTTP status codes returned by a server response.

Here is the code skeleton showing handling of the exceptions listed above. Of course, you don't have to show messages, but do something more useful. And, you don't need to handle all of them; it's upon you which exceptions and how you will handle:

uses
  IdHTTP, IdException, IdStack;

procedure TForm1.Button1Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
begin
  IdHTTP := TIdHTTP.Create;
  try
    try
      IdHTTP.Get('http://www.example.com');
    except
      // this exception class covers the HTTP protocol errors; you may read the
      // response code using ErrorCode property of the exception object, or the
      // same you can read from the ResponseCode property of the TIdHTTP object
      on E: EIdHTTPProtocolException do
        ShowMessage('Indy raised a protocol error!' + sLineBreak +
          'HTTP status code: ' + IntToStr(E.ErrorCode) + sLineBreak +
          'Error message' + E.Message);
      // this exception class covers the cases when the server side closes the
      // connection with a client in a "peaceful" way
      on E: EIdConnClosedGracefully do
        ShowMessage('Indy reports, that connection was closed gracefully!');
      // this exception class covers all the low level socket exceptions
      on E: EIdSocketError do
        ShowMessage('Indy raised a socket error!' + sLineBreak +
          'Error code: ' + IntToStr(E.LastError) + sLineBreak +
          'Error message' + E.Message);
      // this exception class covers all exceptions thrown by Indy library
      on E: EIdException do
        ShowMessage('Indy raised an exception!' + sLineBreak +
          'Exception class: ' + E.ClassName + sLineBreak +
          'Error message: ' + E.Message);
      // this exception class is a base Delphi exception class and covers here
      // all exceptions different from those listed above
      on E: Exception do
        ShowMessage('A non-Indy related exception has been raised!');
    end;
  finally
    IdHTTP.Free;
  end;
end;
4
votes

A plain try/except should do the trick:

try
  IdHttp1.Get(...);
  Result:=IdHttp1.ResponseCode=200;
except on EIdException do
  Result:=false;
end;