\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#281: Improvements in System Error Handling}
\date{October 08, 2006}
\author{David Gravereaux}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#281}&\textbf{Improvements in System Error Handling}\\\hline
Author&

David Gravereaux \tipmail{davygrvy}{pobox.com}
\\
Created&Sunday, \(\text{8}^{\text{th}}\) October 2006\\
Type&Project\\
Tcl Version&\(8.7\)\\
State&Draft\\
Vote&Pending\\
Version&\tipversion$Revision: 1.7 $\\
Keywords&POSIX, channel driver, errorCode\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP describes the need for better error codes and message handling of system errors to be returned to scripts.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

The current method for handling of system errors is done via the \textit{Tcl\_PosixError()} API call. Its job is to grab the value of \textit{errno} and format it for display to a script within the \textbf{errorCode} special variable.

Unfortunately, not all such system errors are left in \textit{errno} and on Windows, not all information can be translated effectively to a POSIX error code without loss of valuable information to the user.

On UNIX, \textit{gethostbyname()} for example, leaves its errors in \textit{h\_errno} [\url{http://www.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html}]. If we look at our use of \textit{gethostbyname()} in unix/tclUnixChan.c for the \textit{CreateSocketAddress()} function, you'll see we are setting \textit{errno} to a wrong code rather than retrieving the proper error information defined in \textit{netdb.h}.

An example of the current mistranslation would be:
\begingroup\small\begin{verbatim}
% socket foo.example.com 1234
couldn't open socket: host is unreachable
% set errorCode
POSIX EHOSTUNREACH {host is unreachable}
\end{verbatim}
\endgroup

And on Windows:
\begingroup\small\begin{verbatim}
% socket foo.example.com 1234
couldn't open socket: invalid argument
% set errorCode
POSIX EINVAL {invalid argument}
\end{verbatim}
\endgroup

Notice that the two are different as well as wrong. EHOSTUNREACH is a routing error at the IP level and is returned by connect(), send().. etc., not by gethostbyname(). For windows, the error translation function TclWinConvertWSAError() sets \textit{errno} to EINVAL for a WSAHOST\_NOT\_FOUND even though the code in CreateSocketAddress() appears to set errno to EHOSTUNREACH. What I would like to see is the following (on all platforms):
\begingroup\small\begin{verbatim}
% socket foo.example.com 1234
couldn't open socket: No such host is known
% set errorCode
NETDB HOST_NOT_FOUND {No such host is known}
\end{verbatim}
\endgroup

If we could specify a place from where the error could be retrieved along with the formatting functions for that type, Tcl's error information to the user would be improved.

A facility to extend/add formatters would also help extension authors.

For example with the windows port of Expect, there are numerous specific errors that Expect could return regarding how the Console API debugger was unable to function, but the error path is only limited to POSIX pipe errors rather than anything specific.

I tried to make a facility to manage these specific errors in a controlled way using a message catalog [\url{http://www.pobox.com/~davygrvy/expect-src/win/expWinErr.mc}] to compile into the expect dll a ``windows''-ish style of error management along with a specific ``EXPECT'' formatter, see ExpWinError() [last function in file] [\url{http://www.pobox.com/~davygrvy/expect-src/win/expWinUtils.cpp}]. I used the ``customer'' bit in the \textbf{errorCode} as a key to forward to the ``WINDOWS'' formatter and thought it was quite smart of me.

But alas... the POSIX restriction was not to be bypassed in a manageable manner.

\section{Reference Implementation}

A reference implementation is not done at this time. An experimental WINDOWS \textbf{errorCode} formatter can be seen @ [\url{http://iocpsock.cvs.sourceforge.net/iocpsock/iocpsock/tclWinError.c?revision=HEAD&view=markup}]

\section{Copyright}

This document is in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
