TIP: 428 Title: Produce Error Dictionary from 'fconfigure -error' Version: $Revision: 1.26 $ Author: Harald Oehlmann Author: Harald Oehlmann 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.