2

I have the following function that raises an exception:

procedure Test();
var
  WinHttpReq: Variant;
begin
  WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
  try
    WinHttpReq.Open('POST', 'https://tv.eurosport.com/', False);
    WinHttpReq.SetRequestHeader('Content-Type', 'application/json');
    WinHttpReq.Send('');
  except
    MsgBox(GetExceptionMessage, mbError, MB_OK);
  end;
end;

Instead obtaining the error in a string GetExceptionMessage, I would like to obtain the error as an integer.

Is this possible?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
yuval
  • 2,848
  • 4
  • 31
  • 51
  • I would like to handle the SSL Certificate error and I think relying on a string as a constant is bad practice. – yuval Mar 21 '16 at 18:48
  • If there is no way to get the Error Code then I will rely on the string. – yuval Mar 21 '16 at 18:49
  • For example: `if ErrorCode = SSL_CERTIFCATE_ERROR then doStuff()` and not `if GetExceptionMessage = 'WinHttp.WinHttpRequest: the host name in the certificate is invalid or does not match' then doStuff()` – yuval Mar 21 '16 at 18:53

1 Answers1

1

Exceptions do not have any code in general. So there's no generic way to retrieve a code from an exception.

In this particular case the exception is based on an OLE automation error, which does have a code. Though, the code is not preserved, when the Inno Setup raises the exception for IDispatch interfaces (OLE).


What you can do, is to use the IUnknown interface. For that you need to:

  • define a Pascal-style interface for the IWinHttpRequest
  • define CLSID_WinHttpRequest
  • instantiate the object using the CreateComObject (instead of the CreateOleObject).
  • call the Send method defined as function Send(Body: Variant): HResult
  • check the returned HResult for 12038 (ERROR_INTERNET_SEC_CERT_CN_INVALID).

Particularly the first step is a huge and an error-prone task.


For examples and details, see:


If you decide to stick with error message comparison, you may try to use the FormatMessage function to retrieve the system/localized error message to compare with. See How i can retrieve the error description for a WinInet error code from delphi.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • I was hoping for something simpler, so what do you recommend relying on the string or the integer? – yuval Mar 21 '16 at 18:59
  • I don't think it's to relevant as to what I want to do after the exception but nevertheless I will explain. If there is a certificate validation error I will try the same request on HTTP and not HTTPS. On the application I am developing there are rare instances of clients that have support for HTTP but on HTTPS have certificate validation errors. – yuval Mar 21 '16 at 19:04
  • Well it matters then. As you can have the `WinHttpRequest` ignore certificate errors, avoiding getting the error in the first place. So you won't have to detect the error. – Martin Prikryl Mar 21 '16 at 19:09
  • Anyway, to answer your question. It's pretty difficult to define the interface correctly. I wouldn't even try. – Martin Prikryl Mar 21 '16 at 19:11
  • I've added one more hint to my answer. – Martin Prikryl Mar 21 '16 at 19:14