TIP #428: PRODUCE ERROR DICTIONARY FROM 'FCONFIGURE -ERROR' ============================================================= Version: $Revision: 1.26 $ Author: Harald Oehlmann Harald Oehlmann State: Draft Type: Project Tcl-Version: 8.7 Vote: Pending Created: Sunday, 16 March 2014 URL: https://tip.tcl-lang.org428.html Post-History: ------------------------------------------------------------------------- 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. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows