I'm struggeling with how to capture the exception cause when I send a RESTRequest to a server which isn't available at the time of the request.
I do get an exception, but it's really a poor exception to work with when I need to present a error message dialog to the user and e.g. disconnect the client.
Question is: How am I supposed to capture the "right" exception in my application, the details of which are "hidden" and end up as a relatively useless ERESTException
?
This is not an EHTTPProtocolException
, so the event on the client or request will not occur on this error.
BTW. Using Delphi 10.2.1.
The ERESTException.Message
I receive back, looks like this:
Exception REST request failed: Error sending data: (12029) A connection with the server could not be established
I'm using TRESTClient
, TRESTRequest
and TRESTResponse
.
When I execute a request to an offline REST service it fails (of course)
System.Net.HttpClient.Win
function TWinHTTPClient.DoExecuteRequest(const ARequest: THTTPRequest; var AResponse: THTTPResponse;
const AContentStream: TStream): TWinHTTPClient.TExecutionResult;
.....
// Send Request
LRes := WinHttpSendRequest(LRequest.FWRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, LDataLength, 0);
if not LRes then
begin
LastError := GetLastError; // this returns 1209
case LastError of
ERROR_WINHTTP_SECURE_FAILURE:
Exit(TExecutionResult.ServerCertificateInvalid);
ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED:
Exit(TExecutionResult.ClientCertificateNeeded);
else
raise ENetHTTPClientException.CreateResFmt(@SNetHttpClientSendError, [GetLastError, SysErrorMessage(GetLastError, GLib.Handle)]);
end;
end;
ENetHTTPClientException
is raised and captured in REST.Client
procedure TCustomRESTRequest.Execute;
try
.....
except
// any kind of server/protocol error
on E: EHTTPProtocolException do
begin
FExecutionPerformance.ExecutionDone;
// we keep measuring only for protocal errors, i.e. where the server actually anwered, not for other exceptions.
LContent := E.ErrorMessage; // Full error description
//Fill RESTResponse with actual response data - error handler might want to access it
ProcessResponse(LURL, LResponseStream, LContent);
if (E.ErrorCode >= 500) and Client.RaiseExceptionOn500 then
raise ERESTException.Create(E.Message);
HandleEvent(DoHTTPProtocolError);
end;
// Unknown error, might even be on the client side. raise it!
on E: Exception do
begin
// If Execute raises an Exception, then the developer should have look into the actual BaseException
raise ERESTException.CreateFmt(sRESTRequestFailed, [E.Message]);
end;
end;