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.