Tcl Source Code

Artifact [ecd7f931e6]
Login

Artifact ecd7f931e656cf2080904e8d8daec315f45c13e3:

Attachment "1372348.patch" to ticket [1372348fff] added by dgp 2006-02-17 23:15:51.
Index: generic/tclIORChan.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIORChan.c,v
retrieving revision 1.13
diff -u -r1.13 tclIORChan.c
--- generic/tclIORChan.c	15 Feb 2006 15:43:55 -0000	1.13
+++ generic/tclIORChan.c	17 Feb 2006 16:03:45 -0000
@@ -399,10 +399,7 @@
 static void		FreeReflectedChannel(ReflectedChannel *rcPtr);
 static int		InvokeTclMethod(ReflectedChannel *rcPtr,
 			    CONST char *method, Tcl_Obj *argOneObj,
-			    Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr,
-			    int flags);
-
-#define INVOKE_NO_CAPTURE	0x01
+			    Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
 
 /*
  * Global constant strings (messages). ==================
@@ -465,6 +462,7 @@
     Tcl_Obj *resObj;		/* Result data for 'initialize' */
     int methods;		/* Bitmask for supported methods. */
     Channel *chanPtr;		/* 'chan' resolved to internal struct. */
+    Tcl_Obj *err;		/* Error message */
 
     /*
      * Syntax:   chan create MODE CMDPREFIX
@@ -535,14 +533,10 @@
      */
 
     modeObj = DecodeEventMask(mode);
-    result = InvokeTclMethod(rcPtr, "initialize", modeObj, NULL, &resObj,
-	    INVOKE_NO_CAPTURE);
+    result = InvokeTclMethod(rcPtr, "initialize", modeObj, NULL, &resObj);
     Tcl_DecrRefCount(modeObj);
     if (result != TCL_OK) {
-	Tcl_Obj *err = Tcl_NewStringObj("Initialize failure: ", -1);
-
-	Tcl_AppendObjToObj(err, resObj);
-	Tcl_SetObjResult(interp, err);
+	UnmarshallErrorResult(interp, resObj);
 	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
 	goto error;
     }
@@ -554,17 +548,12 @@
      *   Compare open mode against optional r/w.
      */
 
-    Tcl_AppendResult(interp, "Initialize failure: ", NULL);
-
-    if (Tcl_ListObjGetElements(interp, resObj, &listc, &listv) != TCL_OK) {
-	/*
-	 * The function above replaces my prefix in case of an error, so more
-	 * work for us to get the prefix back into the error message
-	 */
-
-	Tcl_Obj *err = Tcl_NewStringObj("Initialize failure: ", -1);
+    if (Tcl_ListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) {
 
-	Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, " initialize\" returned non-list: ", -1);
+	Tcl_AppendObjToObj(err, resObj);
 	Tcl_SetObjResult(interp, err);
 	goto error;
     }
@@ -573,8 +562,9 @@
     while (listc > 0) {
 	if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames,
 		"method", TCL_EXACT, &methIndex) != TCL_OK) {
-	    Tcl_Obj *err = Tcl_NewStringObj("Initialize failure: ", -1);
-
+	    err = Tcl_NewStringObj("chan handler \"", -1);
+	    Tcl_AppendObjToObj(err, cmdObj);
+	    Tcl_AppendToObj(err, " initialize\" returned ", -1);
 	    Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
 	    Tcl_SetObjResult(interp, err);
 	    goto error;
@@ -585,29 +575,42 @@
     }
 
     if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) {
-	Tcl_AppendResult(interp, "Not all required methods supported", NULL);
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, "\" does not support all required methods", -1);
+	Tcl_SetObjResult(interp, err);
 	goto error;
     }
 
     if ((mode & TCL_READABLE) && !HAS(methods, METH_READ)) {
-	Tcl_AppendResult(interp, "Reading not supported, but requested", NULL);
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, "\" lacks a \"read\" method", -1);
+	Tcl_SetObjResult(interp, err);
 	goto error;
     }
 
     if ((mode & TCL_WRITABLE) && !HAS(methods, METH_WRITE)) {
-	Tcl_AppendResult(interp, "Writing not supported, but requested", NULL);
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, "\" lacks a \"write\" method", -1);
+	Tcl_SetObjResult(interp, err);
 	goto error;
     }
 
     if (!IMPLIES(HAS(methods, METH_CGET), HAS(methods, METH_CGETALL))) {
-	Tcl_AppendResult(interp,
-		"'cgetall' not supported, but should be, as 'cget' is", NULL);
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, "\" supports \"cget\" but not \"cgetall\"", -1);
+	Tcl_SetObjResult(interp, err);
 	goto error;
     }
 
     if (!IMPLIES(HAS(methods, METH_CGETALL), HAS(methods, METH_CGET))) {
-	Tcl_AppendResult(interp,
-		"'cget' not supported, but should be, as 'cgetall' is", NULL);
+	err = Tcl_NewStringObj("chan handler \"", -1);
+	Tcl_AppendObjToObj(err, cmdObj);
+	Tcl_AppendToObj(err, "\" supports \"cgetall\" but not \"cget\"", -1);
+	Tcl_SetObjResult(interp, err);
 	goto error;
     }
 
@@ -857,6 +860,7 @@
     }
 
     (void) Tcl_SetReturnOptions(interp, Tcl_NewListObj(numOptions, lv));
+    ((Interp *)interp)->flags &= ~ERR_ALREADY_LOGGED;
 }
 
 int
@@ -1017,7 +1021,7 @@
 	}
     } else {
 #endif
-	result = InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj, 0);
+	result = InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj);
 	if ((result != TCL_OK) && (interp != NULL)) {
 	    Tcl_SetChannelErrorInterp(interp, resObj);
 	}
@@ -1100,7 +1104,7 @@
     /* ASSERT: rcPtr->mode & TCL_READABLE */
 
     toReadObj = Tcl_NewIntObj(toRead);
-    if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj, 0)!=TCL_OK) {
+    if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj)!=TCL_OK) {
 	Tcl_SetChannelError(rcPtr->chan, resObj);
 	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
 	*errorCodePtr = EINVAL;
@@ -1194,7 +1198,7 @@
     /* ASSERT: rcPtr->mode & TCL_WRITABLE */
 
     bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
-    if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj, 0) != TCL_OK) {
+    if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
 	Tcl_SetChannelError(rcPtr->chan, resObj);
 	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
 	*errorCodePtr = EINVAL;
@@ -1284,7 +1288,7 @@
     offObj = Tcl_NewWideIntObj(offset);
     baseObj = Tcl_NewStringObj((seekMode == SEEK_SET) ? "start" :
 	    ((seekMode == SEEK_CUR) ? "current" : "end"), -1);
-    if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj, 0)!=TCL_OK) {
+    if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK) {
 	Tcl_SetChannelError(rcPtr->chan, resObj);
 	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
 	*errorCodePtr = EINVAL;
@@ -1394,8 +1398,7 @@
 #endif
 
     maskObj = DecodeEventMask(mask);
-    (void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL,
-	    INVOKE_NO_CAPTURE);
+    (void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
     Tcl_DecrRefCount(maskObj);
 }
 
@@ -1449,8 +1452,7 @@
 
     blockObj = Tcl_NewBooleanObj(!nonblocking);
 
-    if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj,
-	    0) != TCL_OK) {
+    if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj) != TCL_OK) {
 	Tcl_SetChannelError(rcPtr->chan, resObj);
 	errorNum = EINVAL;
     } else {
@@ -1517,7 +1519,7 @@
 
     optionObj = Tcl_NewStringObj(optionName, -1);
     valueObj = Tcl_NewStringObj(newValue, -1);
-    result = InvokeTclMethod(rcPtr, "configure",optionObj,valueObj, &resObj,0);
+    result = InvokeTclMethod(rcPtr, "configure",optionObj,valueObj, &resObj);
     if (result != TCL_OK) {
 	UnmarshallErrorResult(interp, resObj);
     }
@@ -1609,7 +1611,7 @@
 	optionObj = Tcl_NewStringObj(optionName, -1);
     }
 
-    if (InvokeTclMethod(rcPtr, method, optionObj, NULL, &resObj, 0)!=TCL_OK) {
+    if (InvokeTclMethod(rcPtr, method, optionObj, NULL, &resObj)!=TCL_OK) {
 	UnmarshallErrorResult(interp, resObj);
 	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
 	return TCL_ERROR;
@@ -1964,8 +1966,7 @@
     CONST char *method,
     Tcl_Obj *argOneObj,		/* NULL'able */
     Tcl_Obj *argTwoObj,		/* NULL'able */
-    Tcl_Obj **resultObjPtr,	/* NULL'able */
-    int flags)
+    Tcl_Obj **resultObjPtr)	/* NULL'able */
 {
     int cmdc;			/* #words in constructed command */
     Tcl_Obj *methObj = NULL;	/* Method name in object form */
@@ -2021,7 +2022,7 @@
      */
 
     if (resultObjPtr) {
-	if ((result == TCL_OK) || (flags & INVOKE_NO_CAPTURE)) {
+	if (result == TCL_OK) {
 	    /*
 	     * Ok result taken as is, also if the caller requests that there
 	     * is no capture.
@@ -2032,9 +2033,27 @@
 	    /*
 	     * Non-ok result is always treated as an error. We have to capture
 	     * the full state of the result, including additional options.
+	     *
+	     * This is complex and ugly, and would be completely unnecessary
+	     * if we only added support for a TCL_FORBID_EXCEPTIONS flag.
 	     */
-
-	    result = TCL_ERROR;
+	    if (result != TCL_ERROR) {
+		Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rcPtr->argv);
+		int cmdLen;
+		CONST char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
+		Tcl_Obj *msg = Tcl_NewObj();
+
+		Tcl_IncrRefCount(cmd);
+		TclObjPrintf(NULL, msg, "chan handler returned bad code: %d",
+			result);
+		Tcl_ResetResult(rcPtr->interp);
+		Tcl_SetObjResult(rcPtr->interp, msg);
+		Tcl_LogCommandInfo(rcPtr->interp, cmdString, cmdString, cmdLen);
+		Tcl_DecrRefCount(cmd);
+		result = TCL_ERROR;
+	    }
+	    TclFormatToErrorInfo(rcPtr->interp,
+		    "\n    (chan handler subcommand \"%s\")", method);
 	    resObj = MarshallError(rcPtr->interp);
 	}
 	Tcl_IncrRefCount(resObj);
@@ -2215,8 +2234,7 @@
 	 * No parameters/results.
 	 */
 
-	if (InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	}
 
@@ -2232,8 +2250,7 @@
     case ForwardedInput: {
 	Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead);
 
-	if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	    paramPtr->input.toRead = -1;
 	} else {
@@ -2263,8 +2280,7 @@
 	Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
 		paramPtr->output.buf, paramPtr->output.toWrite);
 
-	if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	    paramPtr->output.toWrite = -1;
 	} else {
@@ -2293,8 +2309,7 @@
 		(paramPtr->seek.seekMode==SEEK_SET) ? "start" :
 		(paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
 
-	if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	    paramPtr->seek.offset = -1;
 	} else {
@@ -2323,8 +2338,7 @@
     case ForwardedWatch: {
 	Tcl_Obj *maskObj = DecodeEventMask(paramPtr->watch.mask);
 
-	(void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL,
-		INVOKE_NO_CAPTURE);
+	(void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
 	Tcl_DecrRefCount(maskObj);
 	break;
     }
@@ -2332,8 +2346,7 @@
     case ForwardedBlock: {
 	Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking);
 
-	if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	}
 	break;
@@ -2343,8 +2356,7 @@
 	Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->setOpt.name, -1);
 	Tcl_Obj *valueObj = Tcl_NewStringObj(paramPtr->setOpt.value, -1);
 
-	if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	}
 	break;
@@ -2357,8 +2369,7 @@
 
 	Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, -1);
 
-	if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	} else {
 	    Tcl_DStringAppend(paramPtr->getOpt.value, TclGetString(resObj),-1);
@@ -2371,8 +2382,7 @@
 	 * Retrieve all options.
 	 */
 
-	if (InvokeTclMethod(rcPtr, "cgetall", NULL, NULL, &resObj,
-		0) != TCL_OK) {
+	if (InvokeTclMethod(rcPtr, "cgetall", NULL, NULL, &resObj) != TCL_OK) {
 	    ForwardSetObjError(paramPtr, resObj);
 	} else {
 	    /*
Index: tests/ioCmd.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/ioCmd.test,v
retrieving revision 1.26
diff -u -r1.26 ioCmd.test
--- tests/ioCmd.test	16 Feb 2006 20:25:07 -0000	1.26
+++ tests/ioCmd.test	17 Feb 2006 16:03:47 -0000
@@ -628,79 +628,79 @@
 test iocmd-21.5 {chan create, bad handler, not a command} {
     catch {chan create {r w} foo} msg
     set msg
-} {Initialize failure: invalid command name "foo"}
+} {invalid command name "foo"}
 test iocmd-21.6 {chan create, initialize failed, bad signature} {
     proc foo {} {}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: wrong # args: should be "foo"}
+} {wrong # args: should be "foo"}
 test iocmd-21.7 {chan create, initialize failed, bad signature} {
     proc foo {} {}
     catch {chan create {r w} ::foo} msg
     rename foo {}
     set msg
-} {Initialize failure: wrong # args: should be "::foo"}
-test iocmd-21.8 {chan create, initialize failed, bad result, not a list} {
+} {wrong # args: should be "::foo"}
+test iocmd-21.8 {chan create, initialize failed, bad result, not a list} -body {
     proc foo {args} {return "\{"}
     catch {chan create {r w} foo} msg
     rename foo {}
-    set msg
-} {Initialize failure: unmatched open brace in list}
-test iocmd-21.9 {chan create, initialize failed, bad result, not a list} {
+    set ::errorInfo
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.9 {chan create, initialize failed, bad result, not a list} -body {
     proc foo {args} {return \{\{\}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: unmatched open brace in list}
-test iocmd-21.10 {chan create, initialize failed, bad result, empty list} {
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.10 {chan create, initialize failed, bad result, empty list} -body {
     proc foo {args} {}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: Not all required methods supported}
-test iocmd-21.11 {chan create, initialize failed, bad result, bogus method name} {
+} -match glob -result {*all required methods*}
+test iocmd-21.11 {chan create, initialize failed, bad result, bogus method name} -body {
     proc foo {args} {return 1}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: bad method "1": must be blocking, cget, cgetall, configure, finalize, initialize, read, seek, watch, or write}
-test iocmd-21.12 {chan create, initialize failed, bad result, bogus method name} {
+} -match glob -result {*bad method "1": must be *}
+test iocmd-21.12 {chan create, initialize failed, bad result, bogus method name} -body {
     proc foo {args} {return {a b c}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: bad method "c": must be blocking, cget, cgetall, configure, finalize, initialize, read, seek, watch, or write}
-test iocmd-21.13 {chan create, initialize failed, bad result, required methods missing} {
+} -match glob -result {*bad method "c": must be *}
+test iocmd-21.13 {chan create, initialize failed, bad result, required methods missing} -body {
     proc foo {args} {return {initialize finalize}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: Not all required methods supported}
-test iocmd-21.14 {chan create, initialize failed, bad result, mode/handler mismatch} {
+} -match glob -result {*all required methods*}
+test iocmd-21.14 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
     proc foo {args} {return {initialize finalize watch read}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: Writing not supported, but requested}
-test iocmd-21.15 {chan create, initialize failed, bad result, mode/handler mismatch} {
+} -match glob -result {*lacks a "write" method}
+test iocmd-21.15 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
     proc foo {args} {return {initialize finalize watch write}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: Reading not supported, but requested}
-test iocmd-21.16 {chan create, initialize failed, bad result, cget(all) mismatch} {
+} -match glob -result {*lacks a "read" method}
+test iocmd-21.16 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
     proc foo {args} {return {initialize finalize watch cget write read}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: 'cgetall' not supported, but should be, as 'cget' is}
-test iocmd-21.17 {chan create, initialize failed, bad result, cget(all) mismatch} {
+} -match glob -result {*supports "cget" but not "cgetall"}
+test iocmd-21.17 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
     proc foo {args} {return {initialize finalize watch cgetall read write}}
     catch {chan create {r w} foo} msg
     rename foo {}
     set msg
-} {Initialize failure: 'cget' not supported, but should be, as 'cgetall' is}
+} -match glob -result {*supports "cgetall" but not "cget"}
 test iocmd-21.18 {chan create, initialize ok, creates channel} -match glob -body {
     proc foo {args} {
 	global  res
@@ -729,7 +729,7 @@
     lappend res [file channel rc*]
     rename foo {}
     set res
-} -result {{} {initialize rc* {read write}} 1 {Initialize failure: Not all required methods supported} {}}
+} -result {{} {initialize rc* {read write}} 1 {*all required methods*} {}}
 
 # --- --- --- --------- --------- ---------
 # Helper commands to record the arguments to handler methods.
@@ -797,10 +797,11 @@
     set res {}
     proc foo {args} {track; oninit; error FOO}
     note [set c [chan create {r w} foo]]
-    note [catch {close $c} msg]; note $msg
+    note [catch {close $c} msg]; note $msg; note $::errorInfo
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO {FOO
+*"close $c"}}
 test iocmd-22.5 {chan finalize, for close, arbitrary result, ignored} -match glob -body {
     set res {}
     proc foo {args} {track; oninit; return SOMETHING}
@@ -816,7 +817,7 @@
     note [catch {close $c} msg]; note $msg
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 {}}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
 test iocmd-22.7 {chan finalize, for close, continue, close error} -match glob -body {
     set res {}
     proc foo {args} {track; oninit; return -code 4}
@@ -824,7 +825,7 @@
     note [catch {close $c} msg]; note $msg
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 {}}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
 test iocmd-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
     set res {}
     proc foo {args} {track; oninit; return -code 777 BANG}
@@ -832,7 +833,7 @@
     note [catch {close $c} msg]; note $msg
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 BANG}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
 test iocmd-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
     set res {}
     proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
@@ -840,7 +841,7 @@
     note [catch {close $c} msg opt]; note $msg; note $opt
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
 
 # --- === *** ###########################
 # method read
@@ -903,7 +904,7 @@
     close $c
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!}
+} -result {{read rc* 4096} 1 *bad code*}
 test iocmd-23.6 {chan read, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -915,7 +916,7 @@
     close $c
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!}
+} -result {{read rc* 4096} 1 *bad code*}
 test iocmd-23.7 {chan read, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -927,7 +928,7 @@
     close $c
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!}
+} -result {{read rc* 4096} 1 *bad code*}
 test iocmd-23.8 {chan read, level is squashed} -match glob -body {
     set res {}
     proc foo {args} {
@@ -939,7 +940,7 @@
     close $c
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM! {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BOOM!}}
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
 
 # --- === *** ###########################
 # method write
@@ -1038,7 +1039,7 @@
     close $c
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
 test iocmd-24.10 {chan write, failed write, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
@@ -1048,7 +1049,7 @@
     close $c
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
 test iocmd-24.11 {chan write, failed write, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
@@ -1058,7 +1059,7 @@
     close $c
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
 test iocmd-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit; onfinal; track; return BANG}
@@ -1079,7 +1080,7 @@
     close $c
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM! {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BOOM!}}
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}}
 
 # --- === *** ###########################
 # method cgetall
@@ -1161,7 +1162,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!}
+} -result {{cgetall rc*} 1 *bad code*}
 test iocmd-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1173,7 +1174,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!}
+} -result {{cgetall rc*} 1 *bad code*}
 test iocmd-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1185,7 +1186,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!}
+} -result {{cgetall rc*} 1 *bad code*}
 test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1197,7 +1198,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}}
 
 # --- === *** ###########################
 # method configure
@@ -1245,7 +1246,7 @@
     close $c
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
 test iocmd-26.5 {chan configure, set option, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1257,7 +1258,7 @@
     close $c
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
 test iocmd-26.6 {chan configure, set option, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1269,7 +1270,7 @@
     close $c
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
 test iocmd-26.7 {chan configure, set option, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1281,7 +1282,7 @@
     close $c
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}}
 
 # --- === *** ###########################
 # method cget
@@ -1330,7 +1331,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BOOM!}
+} -result {{cget rc* -rc-foo} 1 *bad code*}
 test iocmd-27.5 {chan configure, get option, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1342,7 +1343,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BOOM!}
+} -result {{cget rc* -rc-foo} 1 *bad code*}
 test iocmd-27.6 {chan configure, get option, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {
@@ -1354,7 +1355,7 @@
     close $c
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}}
 
 # --- === *** ###########################
 # method seek
@@ -1385,7 +1386,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!}
+} -result {{seek rc* 0 current} 1 *bad code*}
 test iocmd-28.4 {chan tell, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
@@ -1394,7 +1395,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!}
+} -result {{seek rc* 0 current} 1 *bad code*}
 test iocmd-28.5 {chan tell, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
@@ -1403,7 +1404,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!}
+} -result {{seek rc* 0 current} 1 *bad code*}
 test iocmd-28.6 {chan tell, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
@@ -1412,7 +1413,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
 test iocmd-28.7 {chan tell, regular return} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return 88}
@@ -1466,7 +1467,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!}
+} -result {{seek rc* 0 start} 1 *bad code*}
 test iocmd-28.13 {chan seek, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
@@ -1475,7 +1476,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!}
+} -result {{seek rc* 0 start} 1 *bad code*}
 test iocmd-28.14 {chan seek, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
@@ -1484,7 +1485,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!}
+} -result {{seek rc* 0 start} 1 *bad code*}
 test iocmd-28.15 {chan seek, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
@@ -1493,7 +1494,7 @@
     close $c
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
 test iocmd-28.16 {chan seek, bogus return, negative location} -match glob -body {
     set res {}
     proc foo {args} {oninit seek; onfinal; track; return -45}
@@ -1606,7 +1607,7 @@
     catch {close $c}
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!}
+} -result {{blocking rc* 0} 1 *bad code*}
 test iocmd-29.8 {chan blocking, continue return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
@@ -1615,7 +1616,7 @@
     catch {close $c}
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!}
+} -result {{blocking rc* 0} 1 *bad code*}
 test iocmd-29.9 {chan blocking, custom return is error} -match glob -body {
     set res {}
     proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
@@ -1624,7 +1625,7 @@
     catch {close $c}
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!}
+} -result {{blocking rc* 0} 1 *bad code*}
 test iocmd-29.10 {chan blocking, level is ignored} -match glob -body {
     set res {}
     proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
@@ -1633,7 +1634,7 @@
     catch {close $c}
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}}
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}}
 test iocmd-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
     set res {}
     proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
@@ -1904,7 +1905,7 @@
     } c]
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 {}} \
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob -body {
     set res {}
@@ -1916,7 +1917,7 @@
     } c]
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 {}} \
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
     set res {}
@@ -1928,7 +1929,7 @@
     } c]
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 BANG} \
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
     set res {}
@@ -1940,7 +1941,7 @@
     } c]
     rename foo {}
     set res
-} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2020,7 +2021,7 @@
     } c]
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!} \
+} -result {{read rc* 4096} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
     set res {}
@@ -2036,7 +2037,7 @@
     } c]
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!} \
+} -result {{read rc* 4096} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
     set res {}
@@ -2052,7 +2053,7 @@
     } c]
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM!} \
+} -result {{read rc* 4096} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
     set res {}
@@ -2068,7 +2069,7 @@
     } c]
     rename foo {}
     set res
-} -result {{read rc* 4096} 1 BOOM! {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BOOM!}} \
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2197,7 +2198,7 @@
     } c]
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match glob -body {
     set res {}
@@ -2211,7 +2212,7 @@
     } c]
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match glob -body {
     set res {}
@@ -2225,7 +2226,7 @@
     } c]
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
     set res {}
@@ -2254,7 +2255,7 @@
     } c]
     rename foo {}
     set res
-} -result {{write rc* snarfsnarfsnarf} 1 BOOM! {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BOOM!}} \
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2365,7 +2366,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!} \
+} -result {{cgetall rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
     set res {}
@@ -2382,7 +2383,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!} \
+} -result {{cgetall rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
     set res {}
@@ -2399,7 +2400,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BOOM!} \
+} -result {{cgetall rc*} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
     set res {}
@@ -2417,7 +2418,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cgetall rc*} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2480,7 +2481,7 @@
     } c]
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!} \
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match glob -body {
     set res {}
@@ -2497,7 +2498,7 @@
     } c]
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!} \
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match glob -body {
     set res {}
@@ -2514,7 +2515,7 @@
     } c]
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BOOM!} \
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -body {
     set res {}
@@ -2532,7 +2533,7 @@
     } c]
     rename foo {}
     set res
-} -result {{configure rc* -rc-foo bar} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2598,7 +2599,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BOOM!} \
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match glob -body {
     set res {}
@@ -2615,7 +2616,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BOOM!} \
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -body {
     set res {}
@@ -2633,7 +2634,7 @@
     } c]
     rename foo {}
     set res
-} -result {{cget rc* -rc-foo} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}} \
     -constraints {testchannel testthread}
 
 # --- === *** ###########################
@@ -2678,7 +2679,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!} \
+} -result {{seek rc* 0 current} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
     set res {}
@@ -2692,7 +2693,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!} \
+} -result {{seek rc* 0 current} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
     set res {}
@@ -2706,7 +2707,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BOOM!} \
+} -result {{seek rc* 0 current} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
     set res {}
@@ -2721,7 +2722,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 current} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
     set res {}
@@ -2804,7 +2805,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!} \
+} -result {{seek rc* 0 start} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
     set res {}
@@ -2818,7 +2819,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!} \
+} -result {{seek rc* 0 start} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
     set res {}
@@ -2832,7 +2833,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BOOM!} \
+} -result {{seek rc* 0 start} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
     set res {}
@@ -2847,7 +2848,7 @@
     } c]
     rename foo {}
     set res
-} -result {{seek rc* 0 start} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
     -constraints {testchannel testthread}
 test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -body {
     set res {}
@@ -3008,7 +3009,7 @@
     } c]
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!} \
+} -result {{blocking rc* 0} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
     set res {}
@@ -3022,7 +3023,7 @@
     } c]
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!} \
+} -result {{blocking rc* 0} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
     set res {}
@@ -3036,7 +3037,7 @@
     } c]
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BOOM!} \
+} -result {{blocking rc* 0} 1 *bad code*} \
     -constraints {testchannel testthread}
 test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
     set res {}
@@ -3051,7 +3052,7 @@
     } c]
     rename foo {}
     set res
-} -result {{blocking rc* 0} 1 BANG {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo BANG}} \
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}} \
     -constraints {testchannel testthread}
 test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
     set res {}