Author: Harald Oehlmann <oehhar@users.sourceforge.net>
Author: Harald Oehlmann <harald.oehlmann@users.sourceforge.net>
State: Draft
Type: Project
Vote: Pending
Created: 16-Mar-2014
Post-History:
Keywords: socket,non-blocking,error reporting,option dictionary
Tcl-Version: 8.7
Abstract
This TIP proposes a new method which allows to return the error message and the error code of a background socket error (as reported by fconfigure -error), similar to the option dictionaries produced by catch and try and consumed by return.
Rationale
The error message of a background channel error may be retrieved and cleared by fconfigure channel -error, but there is no access to the error code.
In addition, the error may not be handled in the TCL-like way using catch or try (or just let fail the program).
Specially the new try syntax (see example in the man page) is well suited to handle socket errors. Example:
try {set h [socket $host $port]}\
trap {POSIX ECONNREFUSED} {} {
# handle not open port
}
Drivers mostly use POSIX errors to report issues where the error code is more portable than the error message (AFAIK).
To handle an error by try, the error must be thrown.
We are limited to an option to the command fconfigure, as this is implemented within the driver interface.
Throwing the error would change the semantics of fconfigure and thus should not happen (consensus on the core list). Instead, the new fconfigure operation should return the error message and the error code.
To finally throw the error, an utility function (chan throwerror $h) may be defined in TCL. This is not part of this TIP.
Proposed Change
The option fconfigure channel -error should be extended to take an optional argument as follows:
fconfigure channel -error ?errorDictVar?
If the optional argument errorDictVar is given, the following dict is written in the named variable of the caller environment:
if there is no error, it should be set to -code 0
if there is an error, it should be set to **-code 1 -errorcode ** errorCode
This is executed in addition to the standard action of fconfigure channel -error.
Example
Usage example with failing async connect:
% set h [connect -async localhost 30001]
d00000af
% fileevent $h writable {set x 1}
% vwait x
% fconfigure $h -error errorDict
connection refused
% set errorDict
-code 1 -errorcode {POSIX ECONNREFUSED {connection refused}}
% close $h
The following example demonstrates the implementation of chan throwerror eg to throw the error from the provided dict.
proc throwerror {h} {
set errorMessage [fconfigure $h -errorDict]
return -options $errorDict $errorMessage
}
Alternatives
Revision 1.11 of this TIP proposed to really throw the error.
Revision 1.21 of this TIP proposed a new option to return an error dict directly.
Implementation
The tip is implemented in fossil branch tip-428.
Remarks
The idea of this semantics and a feasability study is from Reinhard Max.
Copyright
This document has been placed in the public domain.