Why does GetLastError have an error before starting my program?

When used GetLastError

after a Windows API wrapper call, for example ExtractShortPathName

, I noticed that I was GetLastError

returning a non-zero error code regardless of whether the call was ExtractShortPathName

successful or unsuccessful. In fact, it seems like there is a "last error" before my program even executes eg.

program TestGetLastError;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

var
  ErrorCode: Integer;

begin
  try
    ErrorCode := GetLastError;
    if ErrorCode <> 0 then
      RaiseLastOSError;
  except
    on E: Exception do
      WriteLn(E.ClassName, ': ', E.Message);
  end;
end.

      

leads to:

EOSError: System Error.  Code: 122.
The data area passed to a system call is too small

      

Am I misunderstanding something or is there something wrong?

If the Delphi runtime does something that leads to an installation GetLastError

, what is the correct way to clear this error before running my program? Should I use SetLastError(ERROR_SUCCESS);

like this example from the Delphi API documentation:

procedure TForm2.btRaiseLastClick(Sender: TObject);
begin
  { Set the last OS error to a bogus value. }
  System.SetLastError(ERROR_ACCESS_DENIED);

  try
    RaiseLastOSError();
  except
    on Ex : EOSError do
      MessageDlg('Caught an OS error with code: ' + IntToStr(Ex.ErrorCode), mtError, [mbOK], 0);
  end;

  { Let the Delphi Exception dialog appear. }
  RaiseLastOSError(ERROR_NOT_ENOUGH_MEMORY);

  { Finally set the last error to none. }
  System.SetLastError(ERROR_SUCCESS);

  if GetLastError() <> ERROR_SUCCESS then
    MessageDlg('Whoops, something went wrong in the mean time!', mtError, [mbOK], 0);

  { No exception should be thrown here because last OS error is "ERROR_SUCCESS". }
  CheckOSError(GetLastError());
end;

      

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/LastOSError_(Delphi)

+3


source to share


2 answers


The GetLastError documentation indicates that this is only useful if

  • no API call is made and
  • the function that is not working indicates that you can use GetLastError to get more information on why. From this documentation ( emphasis mine )


The return value is the last error code of the calling thread.

The Return Value section of the documentation for each function that sets the last error code notes the conditions under which the function sets the last error code. Most of the functions that set the latest error to the stream of code sets it up when they fail. However, some functions also set the last error code when they succeed. If a function is not documented to set the last error code, the value returned by this function is simply the most recent last error code that was set; some functions set the last error code to 0 on success, while others do not.

This means that calling it without first failing in the function documented to set it on failure doesn't make sense. You cannot call GetLastError unless you know that an error has occurred, and only if you call it after you have called a specific function, it has failed.

+4


source


The value returned GetLastError()

is only meaningful immediately after the Windows API call that failed, and where the documentation for this function indicates that extended error information is available by calling GetLastError()

.

Calling outside of that context will return something from an earlier call, which could be from your code, the Delphi runtime, the DLL you called, or even something in the Windows API ...



As stated in the Windows API documentation for GetLastError()

:

You should immediately call the GetLastError function when the function's return value indicates that such a call will return data.

+13


source







All Articles