Menu

#6 improved error handling

open
nobody
None
5
2014-08-15
2011-08-17
No

The current error handling will fail if a different API function was called since the error occurred since it relies on LastError being set correctly.
This change will solve this issue:

//Handle Exceptions
procedure TCustomComPort.CallException(AnException:Word; const WinError:Int64 =0);
var winmessage:string;
begin
if Assigned(FOnException) then
begin
/// ***** changed by twm 2010-08-12 --- start
if WinError > 0 then begin //get windows error string
winmessage := Format(SOSError, [WinError, SysErrorMessage(WinError)]);
// try Win32Check(winerror = 0); except on E:Exception do WinMessage:=e.message; end;
end;
/// ***** changed by twm 2010-08-12 --- end
FOnException(self,TComExceptions(AnException),ComErrorMessages[AnException],WinError, WinMessage);
end
else
if WinError > 0 then raise EComPort.Create(AnException, WinError)
else raise EComPort.CreateNoWinCode(AnException);
end;

The same code could go into EComport.Create:

// create exception with windows error code
constructor EComPort.Create(ACode: Integer; AWinCode: Integer);
var
winmessage: string;
begin
FWinCode := AWinCode;
FCode := ACode;
// ***** changed by twm --- start
// inherited CreateFmt(ComErrorMessages[ACode] + ' (Error: %d)', [AWinCode]);
if AWinCode then
winmessage := Format(SOSError, [WinError, SysErrorMessage(WinError)])
else
winmessage := SUnkOSError;
inherited Create(_('COM Port Error:') + ' '+ComErrorMessages[ACode]+' (Error: ' + winmessage + ')');
// ***** changed by twm --- end
end;

(If you give me write permissions to the svn repository I will commit these changes myself.
There is some more regarding error handling withing the event thread.)

Discussion

  • Brian Gochnauer

    Brian Gochnauer - 2011-08-17

    That does not compile; at least not under Delphi XE.
    SOSError is a number; Format function is expecting a "Format : string" as a first param

     
  • Brian Gochnauer

    Brian Gochnauer - 2011-08-17

    until you add SysConst.

     
  • Brian Gochnauer

    Brian Gochnauer - 2011-08-17

    Win32Check(winerror = 0);
    in the background Win32Check calls RaiseLastOSError(lasterror) making the call

    Error := EOSError.CreateResFmt(@SOSError, [LastError, SysErrorMessage(LastError)])

    which is essential the same call your making.
    I don't get why you think it relies on LastError?

     
  • Brian Gochnauer

    Brian Gochnauer - 2011-08-17

    I see it.

     
  • Thomas Mueller

    Thomas Mueller - 2011-08-18

    I should have tried to compile it fist :-(

    // create exception with windows error code
    constructor EComPort.Create(ACode: Integer; AWinCode: Integer);
    var
    winmessage: string;
    begin
    FWinCode := AWinCode;
    FCode := ACode;
    // ***** changed by twm --- start
    // inherited CreateFmt(ComErrorMessages[ACode] + ' (Error: %d)', [AWinCode]);
    if AWinCode <> 0 then
    winmessage := Format(SOSError, [AWinCode, SysErrorMessage(AWinCode)])
    else
    winmessage := SUnkOSError;
    inherited Create(_('COM Port Error:') + ' '+ComErrorMessages[ACode]+' (Error: ' + winmessage + ')');
    // ***** changed by twm --- end
    end;

     
  • Thomas Mueller

    Thomas Mueller - 2011-08-18

    @griangochnauer:
    Win32Check uses GetLastError to get the last error code which might have changed in between the failed api function and this call.

    SOSError is a resource string under Delphi 2007 and Delphi XE.

     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.