<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 17 03:33:54 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='221'>
<header><title>Allow Background Error Handlers to Accept Return Options</title><author address="mailto:dgp@users.sf.net">Don Porter</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 2.10 $</status><history></history><created day='15' month='sep' year='2004' /><keyword>bgerror return options</keyword></header>
<abstract>This TIP proposes a new system for registering a background error handler of an interp so that the full set of return options (<tipref type="text" tip="90"/>) can be passed to it.</abstract>
<body><section title="Background">
<para>Whenever a script is evaluated as part of handling an event, and that script evaluation returns TCL_ERROR or some other non-TCL_OK return code it is not equipped to handle, then the code that evaluates that script is expected to call <emph style="italic">Tcl_BackgroundError</emph> to report the exceptional code to the application.</para>
<para>Then <emph style="italic">Tcl_BackgroundError</emph> will arrange for the command <emph style="bold">bgerror</emph> to be called during an idle event. It is intended that each application will define a <emph style="bold">::bgerror</emph> command to its liking so that background errors are reported (or ignored) as the application prefers.</para>
<para>The defined syntax for <emph style="bold">bgerror</emph> is </para>
<quote><emph style="bold">bgerror</emph> <emph style="italic">message</emph></quote>
<para>The <emph style="bold">bgerror</emph> command receives as its only argument a copy of what the interp result was when <emph style="italic">Tcl_BackgroundError</emph> was called. This is presumably an error message.</para>
<para>When <emph style="bold">bgerror</emph> is called, it is also arranged that the variables <emph style="bold">::errorInfo</emph> and <emph style="bold">::errorCode</emph> are set to the same values they had when <emph style="italic">Tcl_BackgroundError</emph> was called. This is effectively another set of arguments passed through a side channel.</para>
<para>Note that the non-TCL_OK return code that triggered the <emph style="italic">Tcl_BackgroundError</emph> call is not itself made known to <emph style="bold">bgerror</emph>. Nor is the <emph style="italic">-level</emph>, <emph style="italic">-errorline</emph>, or other return option information made possible by <tipref type="text" tip="90"/> passed along to <emph style="bold">bgerror</emph> in any way.</para>
</section>
<section title="Proposal">
<para>A new subcommand, <emph style="bold">interp bgerror</emph> will be created that allows for registration of a handler command to react to background errors. Its syntax will be:</para>
<quote><emph style="bold">interp bgerror</emph> <emph style="italic">path</emph> ?<emph style="italic">cmdPrefix</emph>?</quote>
<para>Here <emph style="italic">path</emph> is the path of an interp, interpreted the same way as the <emph style="italic">path</emph> argument to the existing <emph style="bold">interp aliases</emph> subcommand. This argument determines which interp&apos;s background error handler we are interested in. The value of an empty list for <emph style="italic">path</emph> indicates the current interp.</para>
<para>As is the case with other <emph style="bold">interp</emph> subcommands, an alternative means to access the same functionality will be made available as the <emph style="bold">bgerror</emph> subcommand of the <emph style="italic">slave</emph> command of an interp with syntax:</para>
<quote><emph style="italic">slave</emph> <emph style="bold">bgerror</emph> ?<emph style="italic">cmdPrefix</emph>?</quote>
<para>When no <emph style="italic">cmdPrefix</emph> argument is present, the command prefix currently registered to handle background errors in the <emph style="italic">path</emph> interp will be returned. The returned value will be the <emph style="italic">cmdPrefix</emph> argument most recently successfully passed to <emph style="bold">interp bgerror</emph> <emph style="italic">path</emph>, or the default background error handler command of the interp.</para>
<para>When a <emph style="italic">cmdPrefix</emph> argument is present, it must be a valid Tcl list of length at least one. An invalid list or an empty list is an error. A <emph style="italic">cmdPrefix</emph> list argument of length <emph style="italic">N</emph> will become the first <emph style="italic">N</emph> substituted words of the handler command invoked to handle calls to <emph style="italic">Tcl_BackgroundError</emph>. That is, if the <emph style="italic">cmdPrefix</emph> argument is stored in a variable <emph style="bold">cmdPrefix</emph>, subsequent calls to <emph style="italic">Tcl_BackgroundError</emph> will lead to evaluation of a command like so:</para>
<quote><emph style="bold">{expand}$cmdPrefix</emph> <emph style="italic">message</emph> <emph style="italic">returnOptionsDictionary</emph></quote>
<para>The <emph style="italic">message</emph> argument is the interp result at the time <emph style="italic">Tcl_BackgroundError</emph> is called. The <emph style="italic">returnOptionsDictionary</emph> argument is a Tcl dict value (<tipref type="text" tip="111"/>) holding the value of the interp&apos;s return options dictionary at the time <emph style="italic">Tcl_BackgroundError</emph> was called. Specifically, the <emph style="italic">returnOptionsDictionary</emph> argument is the value returned by <emph style="italic">Tcl_GetReturnOptions</emph> (<tipref type="text" tip="227"/>) at the time <emph style="italic">Tcl_BackgroundError</emph> is called.</para>
<para>Stored in the <emph style="italic">returnOptionsDictionary</emph> argument will be values for the <emph style="italic">-level</emph> and <emph style="italic">-code</emph> keys, and when those values indicate a TCL_ERROR triggered the <emph style="italic">Tcl_BackgroundError</emph> call, the <emph style="italic">-errorinfo</emph>, <emph style="italic">-errorcode</emph>, and <emph style="italic">-errorline</emph> keys will have values as well. Any other return options present in the interp&apos;s return options dictionary at the time <emph style="italic">Tcl_BackgroundError</emph> is called will also be available in the <emph style="italic">returnOptionsDictionary</emph> argument.</para>
<para>Note that after this change, applications will be able to register a background error handling command that has no need to consult the variables <emph style="bold">::errorInfo</emph> or <emph style="bold">::errorCode</emph> at all.</para>
</section>
<section title="Compatibility">
<para>Existing applications making use of the <emph style="bold">bgerror</emph> interface provide a <emph style="bold">bgerror</emph> command that expects exactly one argument.</para>
<para>To continue to compatibly support these applications, the default background error handler command prefix registered in each interp will be a command that sets the values of <emph style="bold">::errorInfo</emph> and <emph style="bold">::errorCode</emph> to the values of the corresponding keys in the return options dictionary, if appropriate. Then it will invoke the command <emph style="bold">bgerror</emph> <emph style="italic">message</emph> in the global namespace. For complete compatibility, the existing fallbacks will also be honored in the default handler, including the invoking a hidden command <emph style="bold">bgerror</emph> <emph style="italic">message</emph> in safe interps, and the ultimate fallback (in trusted interps only) being a message written to the stderr channel of the process as determined by <emph style="italic">Tcl_GetStdChannel(TCL_STDERR)</emph>.</para>
</section>
<section title="Rejected Alternatives">
<para>The first draft of this proposal proposed several attempts to call <emph style="bold">bgerror</emph>, first with two arguments, then with one. It was rejected because an error due to calling <emph style="bold">bgerror</emph> with the wrong number of arguments could not be distinguished (easily and reliably) from an error for other reasons. This fallback strategy was prone to the masking of errors.</para>
<para>The new proposal is also preferred over the first draft as it empowers Tcl programmers to leave behind <emph style="bold">bgerror</emph> as a <emph style="italic">magic</emph> command name with special significance to Tcl. Callback registration is a cleaner mechanism then giving particular command names privileged status, and we should move in that direction when the opportunity arises.</para>
<para>An alternative syntax for <emph style="bold">interp bgerror</emph>,</para>
<quote><emph style="bold">interp bgerror</emph> <emph style="italic">path target cmdPrefix</emph></quote>
<para>was considered. This alternative would have allowed background errors in the <emph style="italic">path</emph> interp to be handled in the <emph style="italic">target</emph> interp. The difficulty with this alternative was in how to define the introspection form of the command. Introspection would need to return <emph style="italic">target</emph> information, and it would be possible that the target interp of the handler would be an interp for which no <emph style="italic">target</emph> path could be constructed to be returned (a sibling, parent, or uncle interp, etc.).</para>
<para>The proposed form can be combined with <emph style="bold">interp alias</emph> to still allow background errors in one interp to (ultimately) be handled by a command evaluation in a different interp.</para>
</section>
<section title="Reference Implementation">
<para>See Tcl Patch 1060579.</para>
</section>
<section title="Comments">
<para>Please make any comments here.</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

