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.
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:
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.
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.
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.
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;
A plain try/except should do the trick:
try
IdHttp1.Get(...);
Result:=IdHttp1.ResponseCode=200;
except on EIdException do
Result:=false;
end;