Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct usage of GetLastError and FormatMessage in Delphi?

I have a problem using a third-party component in Delphi 2006 (also Delphi 7), in which I get an "Unspecified Error" when executing a function call to that component. Do you have example code that utilises GetLastError and FormatMessage in Delphi, that would allow me to access more information about the error ? TIA :)

like image 483
Drew Gibson Avatar asked Mar 21 '09 10:03

Drew Gibson


2 Answers

There is an integrated helper function in Delphi: SysErrorMessage. It's essentially a wrapper to FormatMessage, but much simpler to use in your case. Just provide the error code you need a textual description for.

For example you can use this to display the last error:

ShowMessage(SysErrorMessage(GetLastError)) 

If you want to raise an exception with this message, it's even simpler:

RaiseLastOSError; 

Important: Make sure that there is no additional API call between the failing function and your call of GetLastError, otherwise the last error will be reset.

like image 85
Daniel Rikowski Avatar answered Sep 18 '22 18:09

Daniel Rikowski


While DR is correct, there is a problem with this approach: It does not allow you to specify the context in which the error occurred. Ever seen the error "An API function failed." whithout being any wiser which function it was and where it happended?

That's why I wrote the RaiseLastOsErrorEx and Win32CheckEx functions:

procedure RaiseLastOsErrorEx(const _Format: string); begin   RaiseLastOsErrorEx(GetLastError, _Format); end;  procedure RaiseLastOsErrorEx(_ErrorCode: integer; _Format: string); overload; var   Error: EOSError; begin   if _ErrorCode <> ERROR_SUCCESS then     Error := EOSError.CreateFmt(_Format, [_ErrorCode, SysErrorMessage(_ErrorCode)])   else     Error := EOsError.CreateFmt(_Format, [_ErrorCode, _('unknown OS error')]);   Error.ErrorCode := _ErrorCode;   raise Error; end;  function GetLastOsError(out _Error: string; const _Format: string = ''): DWORD; begin   Result := GetLastOsError(GetLastError, _Error, _Format); end;  function GetLastOsError(_ErrCode: integer; out _Error: string; const _Format: string = ''): DWORD; var   s: string; begin   Result := _ErrCode;   if Result <> ERROR_SUCCESS then     s := SysErrorMessage(Result)   else     s := _('unknown OS error');   if _Format <> '' then     try       _Error := Format(_Format, [Result, s])     except       _Error := s;     end else     _Error := s; end;  function Win32CheckEx(_RetVal: BOOL; out _ErrorCode: DWORD; out _Error: string;   const _Format: string = ''): BOOL; begin   Result := _RetVal;   if not Result then     _ErrorCode := GetLastOsError(_Error, _Format); end; 

(They are part of unit u_dzMiscUtils of my dzLib library available here: https://osdn.net/projects/dzlib-tools/svn/view/dzlib/trunk/src/u_dzMiscUtils.pas?view=markup&root=dzlib-tools#l313

like image 34
dummzeuch Avatar answered Sep 18 '22 18:09

dummzeuch