# TIP 428: Produce Error Dictionary from 'fconfigure -error'
	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
	Tcl-Branch:     tip-428
-----

# 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.

