0

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;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
hhaumann
  • 272
  • 2
  • 19
  • 3
    Yeah, it would be nice if the restexception would be thrown using `Exception.RaiseOuterException`, so it's InnerException and BaseException properties would be set. Unfortunately this is one of the many things where Delphi's rest components are lacking. – GolezTrol Feb 28 '19 at 13:01
  • 2
    Agreed. It would be so easy for Embarcadero to grep their RTL/VCL/FMX source code for `raise` statements and update any that are inside `except` blocks to call `RaiseOuterException` instead. They could do it in a single day. Why they haven't done this yet is a disservice, considering `RaiseOuterException` has been available for a long time now. So, as such, you are basically stuck catching the final raised exception and manually parse its `Message` to determine the original error code that was reported, which is never a good thing to resort to. – Remy Lebeau Feb 28 '19 at 23:41
  • Yes, and I noticed this line (above) // If Execute raises an Exception, then the developer should have look into the actual BaseException Sure, but How2Do? As you say @Remy only way is to treat all exceptions equal or start "producing" all kinds of exception to see what may turn up of text messages to decode - kind of sucks :( – hhaumann Mar 01 '19 at 09:10
  • @RemyLebeau - Hi, I ran into that Problem as well, do you know if anything has changed in the last 2 1/2 Years, or does some "Isue Report" on EMBA Ticketsystem exist we can push foreward? – fisi-pjm Jul 26 '21 at 10:05
  • @fisi-pjm nothing has changed. I have created a ticket : https://quality.embarcadero.com/browse/RSP-34446 – Remy Lebeau Jul 26 '21 at 14:28

0 Answers0