What is the correct usage of GetLastError and FormatMessage in Delphi?
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.
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