THRIFT-4886 More detailed error information for WinHTTP transport
Client: Delphi
Patch: Jens Geyer
diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
index d7eefa8..540865f 100644
--- a/lib/delphi/src/Thrift.Transport.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
@@ -297,9 +297,11 @@
 
 procedure TWinHTTPClientImpl.SendRequest;
 var
-  http : IWinHTTPRequest;
+  http  : IWinHTTPRequest;
   pData : PByte;
-  len : Integer;
+  len   : Integer;
+  error : Cardinal;
+  sMsg  : string;
 begin
   http := CreateRequest;
 
@@ -307,12 +309,20 @@
   len   := FOutputMemoryStream.Size;
 
   // send all data immediately, since we have it in memory
-  if not http.SendRequest( pData, len, 0)
-  then raise TTransportExceptionUnknown.Create('send request error '+IntToStr(GetLastError));
+  if not http.SendRequest( pData, len, 0) then begin
+    error := Cardinal( GetLastError);
+    sMsg  := 'WinHTTP send error '+IntToStr(Int64(error))+' '+WinHttpSysErrorMessage(error);
+    raise TTransportExceptionUnknown.Create(sMsg);
+  end;
 
   // end request and start receiving
-  if not http.FlushAndReceiveResponse
-  then raise TTransportExceptionInterrupted.Create('flush/receive error '+IntToStr(GetLastError));
+  if not http.FlushAndReceiveResponse then begin
+    error := Cardinal( GetLastError);
+    sMsg  := 'WinHTTP recv error '+IntToStr(Int64(error))+' '+WinHttpSysErrorMessage(error);
+    if error = ERROR_WINHTTP_TIMEOUT
+    then raise TTransportExceptionTimedOut.Create( sMsg)
+    else raise TTransportExceptionInterrupted.Create( sMsg);
+  end;
 
   FInputStream := THTTPResponseStream.Create(http);
 end;
diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas
index b26f6ba..8179fae 100644
--- a/lib/delphi/src/Thrift.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.WinHTTP.pas
@@ -463,6 +463,8 @@
   ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY            = WINHTTP_ERROR_BASE + 185;
   ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY     = WINHTTP_ERROR_BASE + 186;
 
+  WINHTTP_ERROR_LAST                                  = WINHTTP_ERROR_BASE + 186;
+
 
 const
   WINHTTP_THRIFT_DEFAULTS = WINHTTP_FLAG_NULL_CODEPAGE
@@ -673,6 +675,12 @@
 
   EWinHTTPException = class(Exception);
 
+{ helper functions }
+
+function WinHttpSysErrorMessage( const error : Cardinal): string;
+procedure RaiseLastWinHttpError;
+
+
 implementation
 
 const WINHTTP_DLL = 'WinHTTP.dll';
@@ -697,6 +705,48 @@
 function WinHttpCreateUrl; stdcall; external WINHTTP_DLL;
 
 
+{ helper functions }
+
+function WinHttpSysErrorMessage( const error : Cardinal): string;
+const FLAGS = FORMAT_MESSAGE_ALLOCATE_BUFFER
+           or FORMAT_MESSAGE_IGNORE_INSERTS
+           or FORMAT_MESSAGE_FROM_SYSTEM
+           or FORMAT_MESSAGE_FROM_HMODULE;
+var pBuffer : PChar;
+    nChars : Cardinal;
+begin
+  if (error < WINHTTP_ERROR_BASE)
+  or (error > WINHTTP_ERROR_LAST)
+  then Exit( SysUtils.SysErrorMessage( error));
+
+  pBuffer := nil;
+  try
+    nChars := FormatMessage( FLAGS,
+                             Pointer( GetModuleHandle( WINHTTP_DLL)),
+                             error,
+                             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
+                             @pBuffer, 0,
+                             nil);
+    SetString( result, pBuffer, nChars);
+  finally
+    LocalFree( Cardinal( pBuffer));
+  end;
+end;
+
+
+procedure RaiseLastWinHttpError;
+var error : Cardinal;
+    sMsg  : string;
+begin
+  error := Cardinal( GetLastError);
+  if error <> NOERROR then begin
+    sMSg := IntToStr(Integer(error))+' '+WinHttpSysErrorMessage(error);
+    raise EWinHTTPException.Create( sMsg);
+  end;
+end;
+
+
+
 { misc. record helper }
 
 
@@ -785,7 +835,7 @@
                          PWideChar(Pointer(aProxy)),        // may be nil
                          PWideChar(Pointer(aProxyBypass)),  // may be nil
                          aFlags);
-  if handle = nil then RaiseLastOSError;
+  if handle = nil then RaiseLastWinHttpError;
   inherited Create( handle);
 end;
 
@@ -824,7 +874,7 @@
 begin
   FSession := aSession;
   handle   := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0);
-  if handle = nil then RaiseLastOSError;
+  if handle = nil then RaiseLastWinHttpError;
   inherited Create( handle);
 end;
 
@@ -876,7 +926,7 @@
                                      PWideChar(aReferrer),
                                      @accept,
                                      aFlags);
-  if handle = nil then RaiseLastOSError;
+  if handle = nil then RaiseLastWinHttpError;
   inherited Create( handle);
 end;
 
@@ -1191,6 +1241,9 @@
 end;
 
 
+initialization
+  OutputDebugString( PChar( SysErrorMessage( 12002)));
+
 end.